From da2c0f9a34bd2a3d98b149a693aa173f4cb150dd Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Mon, 5 Oct 2026 08:33:00 +0200 Subject: [PATCH 01/10] Now using global static usings on endpoints to reduce boilerplate --- .../Communications/GetApplicantInviteEndpoint.cs | 1 - .../Communications/GetApplicantInvitesEndpoint.cs | 1 - .../Endpoints/Communications/GetInvitesEndpoint.cs | 2 -- .../Communications/GetNotificationsEndpoint.cs | 2 -- .../Endpoints/Communications/SendInviteEndpoint.cs | 1 - .../Endpoints/Evidence/CreateEvidenceEndpoint.cs | 1 - .../Endpoints/Evidence/CreateIndicatorEndpoint.cs | 1 - .../Endpoints/Evidence/CreateMilestoneEndpoint.cs | 1 - .../Endpoints/Evidence/GetEvidenceEndpoint.cs | 1 - .../Endpoints/Evidence/GetEvidenceFilesEndpoint.cs | 1 - .../Endpoints/Evidence/GetEvidenceUrlEndpoint.cs | 1 - .../Endpoints/Evidence/GetIndicatorEndpoint.cs | 1 - .../Endpoints/Evidence/GetIndicatorsEndpoint.cs | 1 - .../Evidence/GetMilestoneEvidenceEndpoint.cs | 1 - .../Endpoints/Evidence/GetProjectEvidenceEndpoint.cs | 1 - .../Evidence/RecordIndicatorAmountEndpoint.cs | 1 - .../Endpoints/Evidence/UpdateEvidenceEndpoint.cs | 1 - .../Execution/ApproveDisbursementEndpoint.cs | 1 - .../Endpoints/Execution/CreateDisbursementEndpoint.cs | 1 - .../Endpoints/Execution/CreateRiskEndpoint.cs | 1 - .../Endpoints/Execution/CreateRuleEndpoint.cs | 1 - .../Endpoints/Execution/GetDisbursementEndpoint.cs | 1 - .../Endpoints/Execution/GetDisbursementsEndpoint.cs | 1 - .../Endpoints/Execution/GetRiskEndpoint.cs | 1 - .../Endpoints/Execution/GetRisksEndpoint.cs | 1 - .../Endpoints/Execution/GetRuleEndpoint.cs | 1 - .../Endpoints/Execution/GetRulesEndpoint.cs | 1 - .../Endpoints/Execution/UpdateDisbursementEndpoint.cs | 1 - .../Endpoints/Execution/UpdateRiskEndpoint.cs | 1 - .../Endpoints/Execution/UpdateRuleEndpoint.cs | 1 - .../Endpoints/Governance/CreateInstrumentEndpoint.cs | 1 - .../Governance/CreateOrganisationEndpoint.cs | 1 - .../Endpoints/Governance/CreatePortfolioEndpoint.cs | 1 - .../Endpoints/Governance/CreateTenantEndpoint.cs | 1 - .../Endpoints/Governance/DashboardEndpoint.cs | 1 - .../Endpoints/Governance/GetAuditLogsEndpoint.cs | 1 - .../Endpoints/Governance/GetInstrumentsEndpoint.cs | 1 - .../Endpoints/Governance/GetOrganisationEndpoint.cs | 1 - .../Governance/GetOrganisationPortfoliosEndpoint.cs | 1 - .../Endpoints/Governance/GetOrganisationsEndpoint.cs | 1 - .../Endpoints/Governance/GetPorfolioValueEndpoint.cs | 1 - .../Endpoints/Governance/GetPortfolioEndpoint.cs | 1 - .../Governance/GetPortfolioProgrammesEndpoint.cs | 1 - .../Endpoints/Governance/GetPortfoliosEndpoint.cs | 1 - .../Endpoints/Governance/GetProgrammeValueEndpoint.cs | 1 - .../Endpoints/Governance/GetProgrammesEndpoint.cs | 1 - .../Endpoints/Governance/GetTenantEndpoint.cs | 1 - .../Governance/GetTenantOrganisationsEndpoint.cs | 1 - .../Endpoints/Governance/GetTenantsEndpoint.cs | 1 - .../Endpoints/Governance/UpdateInstrumentEndpoint.cs | 1 - .../Governance/UpdateOrganisationEndpoint.cs | 1 - .../Endpoints/Governance/UpdatePortfolioEndpoint.cs | 1 - .../Endpoints/Governance/UpdateTenantEndpoint.cs | 1 - .../Endpoints/Grants/CreateAwardEndpoint.cs | 1 - .../Endpoints/Grants/CreateBudgetEndpoint.cs | 1 - .../Endpoints/Grants/CreateContractEndpoint.cs | 1 - .../Endpoints/Grants/ExecuteContractEndpoint.cs | 1 - .../Endpoints/Grants/GetAwardEndpoint.cs | 1 - .../Endpoints/Grants/GetAwardsEndpoint.cs | 1 - .../Endpoints/Grants/GetBudgetEndpoint.cs | 1 - .../Endpoints/Grants/GetBudgetsEndpoint.cs | 1 - .../Endpoints/Grants/GetContractEndpoint.cs | 1 - .../Endpoints/Grants/GetContractUrlEndpoint.cs | 1 - .../Endpoints/Grants/GetContractsEndpoint.cs | 1 - .../Endpoints/Grants/UpdateBudgetEndpoint.cs | 1 - .../Endpoints/Grants/UpdateContractEndpoint.cs | 1 - .../Endpoints/Grants/UploadContractEndpoint.cs | 1 - .../Endpoints/Projects/CreateActivityEndpoint.cs | 1 - .../Endpoints/Projects/CreateBeneficiaryEndpoint.cs | 1 - .../Endpoints/Projects/CreateChangeRequestEndpoint.cs | 1 - .../Projects/CreateComplianceItemEndpoint.cs | 1 - .../Endpoints/Projects/CreateIssueEndpoint.cs | 1 - .../Endpoints/Projects/CreateOutcomeEndpoint.cs | 1 - .../Endpoints/Projects/CreateProgrammeEndpoint.cs | 1 - .../Endpoints/Projects/CreateProjectEndpoint.cs | 1 - .../Endpoints/Projects/CreateSiteVisitEndpoint.cs | 1 - .../Endpoints/Projects/GetActivitiesEndpoint.cs | 1 - .../Endpoints/Projects/GetActivityEndpoint.cs | 1 - .../Endpoints/Projects/GetBeneficiariesEndpoint.cs | 1 - .../Endpoints/Projects/GetBeneficiaryEndpoint.cs | 1 - .../Endpoints/Projects/GetChangeRequestEndpoint.cs | 1 - .../Endpoints/Projects/GetChangeRequestsEndpoint.cs | 1 - .../Endpoints/Projects/GetComplianceItemEndpoint.cs | 1 - .../Endpoints/Projects/GetComplianceItemsEndpoint.cs | 1 - .../Endpoints/Projects/GetIssueEndpoint.cs | 1 - .../Endpoints/Projects/GetIssuesEndpoint.cs | 1 - .../Endpoints/Projects/GetMilestoneEndpoint.cs | 1 - .../Endpoints/Projects/GetMilestonesEndpoint.cs | 1 - .../Endpoints/Projects/GetOutcomeEndpoint.cs | 1 - .../Endpoints/Projects/GetOutcomesEndpoint.cs | 1 - .../Endpoints/Projects/GetProgrammeEndpoint.cs | 1 - .../Projects/GetProgrammeProjectsEndpoint.cs | 1 - .../Endpoints/Projects/GetProgrammesEndpoint.cs | 1 - .../Endpoints/Projects/GetProjectEndpoint.cs | 1 - .../Projects/GetProjectIndicatorsEndpoint.cs | 1 - .../Projects/GetProjectMilestonesEndpoint.cs | 1 - .../Endpoints/Projects/GetProjectRisksEndpoint.cs | 1 - .../Endpoints/Projects/GetProjectsEndpoint.cs | 1 - .../Endpoints/Projects/GetSiteVisitEndpoint.cs | 1 - .../Endpoints/Projects/GetSiteVisitsEndpoint.cs | 1 - .../Endpoints/Projects/UpdateBeneficiaryEndpoint.cs | 1 - .../Endpoints/Projects/UpdateChangeRequestEndpoint.cs | 1 - .../Projects/UpdateComplianceItemEndpoint.cs | 1 - .../Endpoints/Projects/UpdateIssueEndpoint.cs | 1 - .../Endpoints/Projects/UpdateMilestoneEndpoint.cs | 1 - .../Endpoints/Projects/UpdateOutcomeEndpoint.cs | 1 - .../Endpoints/Projects/UpdateProgrammeEndpoint.cs | 1 - .../Endpoints/Projects/UpdateProjectEndpoint.cs | 1 - .../Endpoints/Projects/UpdateProjectStatusEndpoint.cs | 1 - .../Endpoints/Projects/UpdateSiteVisitEndpoint.cs | 1 - .../Endpoints/Users/CreateUserEndpoint.cs | 11 +++++++++-- .../Endpoints/Users/GetUserEndpoint.cs | 1 - .../Endpoints/Users/GetUsersEndpoint.cs | 1 - .../Endpoints/Users/SyncUserEndpoint.cs | 1 - .../Endpoints/Users/UpdateUserStatusEndpoint.cs | 1 - PostFundManagement.Api/PostFundManagement.Api.csproj | 6 ++++++ 116 files changed, 15 insertions(+), 118 deletions(-) diff --git a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs index 469030c..fa5e435 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInviteEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs index 62ff7be..22b4d41 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetApplicantInvitesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs index c4932e6..6ab11d0 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetInvitesEndpoint.cs @@ -4,8 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using static PostFundManagement.Application.Extensions.General; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs index 80e2d30..f8d1b8c 100644 --- a/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/GetNotificationsEndpoint.cs @@ -4,8 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using static PostFundManagement.Application.Extensions.General; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs index 79c606a..97f45ca 100644 --- a/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Communications/SendInviteEndpoint.cs @@ -5,7 +5,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Communications; diff --git a/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs index 62e123d..e16d041 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/CreateEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs index f4caad6..70e563d 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/CreateIndicatorEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Evidence; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs index eea7d47..90a5343 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/CreateMilestoneEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Evidence; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs index 0222ef2..24b2e17 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs index 0624477..32eb996 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceFilesEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs index 3c910d5..188fb18 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetEvidenceUrlEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs index d36afa5..292311a 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs index e4b500a..c23a25b 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetIndicatorsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs index f65efb8..59a8cda 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetMilestoneEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs index c39e9ec..3ebac97 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/GetProjectEvidenceEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs index 3c617ac..c76f0f3 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/RecordIndicatorAmountEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs b/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs index 4db42ba..eddb256 100644 --- a/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Evidence/UpdateEvidenceEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Evidence; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Evidence; diff --git a/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs index 3424687..8fae8cb 100644 --- a/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/ApproveDisbursementEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs index cbc225d..623c676 100644 --- a/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/CreateDisbursementEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs index f9418c4..f272f78 100644 --- a/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/CreateRiskEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs index 6a093b7..b4eccbb 100644 --- a/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/CreateRuleEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs index 95118d4..ca185d1 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs index b498ec2..2cdb88d 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetDisbursementsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs index 9d78329..3b4539e 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRiskEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs index ecd2fb6..d0cb01f 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRisksEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs index 11ecc5e..79f0b5f 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRuleEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs index 1ca8f40..37167ef 100644 --- a/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/GetRulesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs index 8ecb1ae..cc955e2 100644 --- a/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/UpdateDisbursementEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs index b0d0f70..cbbc176 100644 --- a/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/UpdateRiskEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs b/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs index ff8f53a..8fc7880 100644 --- a/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Execution/UpdateRuleEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Execution; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Execution; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs index 80a6073..e382dc5 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreateInstrumentEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs index 334bde9..5146d0b 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreateOrganisationEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs index 8c38558..d85f8f8 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreatePortfolioEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs index 6f0fffa..3cd15b5 100644 --- a/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/CreateTenantEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs index 572f11e..12766ba 100644 --- a/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/DashboardEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs index 7f086d0..1f2b0e9 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetAuditLogsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs index 83db06a..cffe719 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetInstrumentsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs index 96f841b..3c4f3ce 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs index 496a984..698bbcf 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationPortfoliosEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs index 3f08d06..0cbf1c8 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetOrganisationsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs index 82d22ae..451de3b 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPorfolioValueEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs index 8229e24..6c20b65 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs index b2f5f56..479738d 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPortfolioProgrammesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs index 311ec87..deef39e 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetPortfoliosEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs index fc3de4f..7140de3 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetProgrammeValueEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs index aabc0f5..f000a72 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetProgrammesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs index 850aeeb..86816ad 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetTenantEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs index 0d22bcf..80dc27c 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Entities; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs index e4f954c..64475d7 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetTenantsEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Entities; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs index 292b542..4246258 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdateInstrumentEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs index c493bc9..21964d8 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdateOrganisationEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs index d8cc5d9..385fd8a 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdatePortfolioEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs index ca065eb..8e36634 100644 --- a/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/UpdateTenantEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Governance; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs index 7e2ee74..377f5bd 100644 --- a/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/CreateAwardEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs index 6e104e1..56bd98a 100644 --- a/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/CreateBudgetEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs index 8d2b2b6..aab4043 100644 --- a/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/CreateContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs index a57a7bd..d2e80d5 100644 --- a/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/ExecuteContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs index 76162ca..1524d88 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetAwardEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs index 393b8ee..06c3a79 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetAwardsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs index c7f0696..c8b8cfb 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetBudgetEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs index 30b84d5..69f1137 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetBudgetsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs index 46ea9b1..4730670 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs index efa6aab..88d7956 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetContractUrlEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs index 4595a7f..bc5f4b8 100644 --- a/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/GetContractsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs index 5bea5a6..5a82bfe 100644 --- a/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/UpdateBudgetEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs index e2bc190..bb480b3 100644 --- a/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/UpdateContractEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Grants; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs b/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs index 0d6ec67..b7071ec 100644 --- a/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Grants/UploadContractEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Grants; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs index 30f7b2f..e1ab7a9 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateActivityEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs index 51312b2..1acab9e 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateBeneficiaryEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs index 1cf7e7f..7b6f4ef 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateChangeRequestEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs index 921972d..644bce6 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateComplianceItemEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs index ffc1f99..18fba1c 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateIssueEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs index ded7561..7b85f6b 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateOutcomeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs index af1119f..438b795 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateProgrammeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs index 9c9d352..3da9e67 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateProjectEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs index 0be71f6..2ad2cb3 100644 --- a/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/CreateSiteVisitEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs index 7fa0c10..70a25f4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetActivitiesEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs index 2cd9be9..d8fa107 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetActivityEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs index f8a86fc..23093e4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiariesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs index 1cae920..040c33c 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetBeneficiaryEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs index 071cbad..a0bc0f4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs index 1a192cc..462acb8 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetChangeRequestsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs index b910f67..5229d77 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs index 08fef13..5d94dd6 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetComplianceItemsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs index b2882cd..921a9e8 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetIssueEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs index 35db03a..efd4ac0 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetIssuesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs index c4573bc..49cd9e5 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetMilestoneEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs index 62efa73..a4f03e4 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetMilestonesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs index 44b84ce..c461a81 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetOutcomeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs index 96e5c96..cd7d4d6 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetOutcomesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs index 2084381..3e13e39 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs index 3cd77ca..929a9dc 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProgrammeProjectsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs index dab6d2a..3362d77 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProgrammesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs index 17b8d4b..7a445fb 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs index a36b877..c6be951 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectIndicatorsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs index 26e5567..493b68b 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectMilestonesEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs index 2ebea23..da811dc 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectRisksEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs index fd3aff8..3b9daf8 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetProjectsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs index a9d224f..279bd66 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs index 8259aac..07c2e1f 100644 --- a/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/GetSiteVisitsEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs index 580fd3e..52fdd25 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateBeneficiaryEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs index d9eecea..e4d1795 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateChangeRequestEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs index 134af82..8f72bd1 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateComplianceItemEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs index 2a2033f..42d84c7 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateIssueEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs index 7ef1ebb..b529654 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateMilestoneEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs index de8a0dd..019acdb 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateOutcomeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs index f1497dc..98b9845 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateProgrammeEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs index 0c9d6aa..79d14e0 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs index dc08e86..c4a3d5c 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateProjectStatusEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs b/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs index 3513f13..205850d 100644 --- a/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Projects/UpdateSiteVisitEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Application.Services.Projects; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Projects; diff --git a/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs index fca9d81..e994f7e 100644 --- a/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs @@ -1,5 +1,12 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Domain.Abstractions; -public class CreateUserEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class CreateUserEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + throw new NotImplementedException(); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs index a32ee3c..fde821b 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; diff --git a/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs index a3b4915..15e610c 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUsersEndpoint.cs @@ -5,7 +5,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; diff --git a/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs index 6fee673..faea1cc 100644 --- a/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/SyncUserEndpoint.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; diff --git a/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs index 3c48131..8159eb6 100644 --- a/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/UpdateUserStatusEndpoint.cs @@ -4,7 +4,6 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; -using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails; namespace PostFundManagement.Api.Endpoints.Users; diff --git a/PostFundManagement.Api/PostFundManagement.Api.csproj b/PostFundManagement.Api/PostFundManagement.Api.csproj index b1f4f21..26284aa 100644 --- a/PostFundManagement.Api/PostFundManagement.Api.csproj +++ b/PostFundManagement.Api/PostFundManagement.Api.csproj @@ -87,6 +87,12 @@ + + + + + + From 1ebd83a2f49dafb78e7f2faf7364fbcb80d372cf Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Mon, 5 Oct 2026 08:57:39 +0200 Subject: [PATCH 02/10] Removed repetetive static usings and aliases --- .../PostFundManagement.Api.csproj | 2 +- .../Abstractions/Services/IToolService.cs | 6 - .../Extensions/Postgres.cs | 1 - .../Extensions/Quartz.cs | 1 - .../Extensions/S3.cs | 1 - .../Extensions/Security.cs | 1 - .../Filters/ActiveUserFilter.cs | 2 - .../Filters/UserRoleFilter.cs | 1 - .../PostFundManagement.Application.csproj | 6 + .../CommunicationsCacheService.cs | 1 - .../Services/Communications/Records.cs | 1 - .../Services/Evidence/EvidenceCacheService.cs | 1 - .../Services/Evidence/Records.cs | 1 - .../Execution/ExecutionCacheService.cs | 1 - .../Services/Execution/Records.cs | 1 - .../Governance/GovernanceCacheService.cs | 1 - .../Services/Governance/Records.cs | 1 - .../Services/Grants/GrantsCacheService.cs | 1 - .../Services/Grants/Records.cs | 1 - .../Services/Projects/ProjectCacheService.cs | 1 - .../Services/Projects/Records.cs | 1 - .../Services/Shared/GeneralS3Service.cs | 1 - .../Services/Users/UserCacheService.cs | 1 - .../Entities/Activity.cs | 1 - .../Entities/AuditLog.cs | 2 - .../Entities/Beneficiary.cs | 1 - PostFundManagement.Domain/Entities/Budget.cs | 1 - .../Entities/ChangeRequest.cs | 1 - .../Entities/ComplianceItem.cs | 1 - .../Entities/Indicator.cs | 1 - .../Entities/Instrument.cs | 1 - PostFundManagement.Domain/Entities/Issue.cs | 1 - .../Entities/Milestone.cs | 1 - .../Entities/Notification.cs | 1 - .../Entities/Organisation.cs | 2 - PostFundManagement.Domain/Entities/Outcome.cs | 1 - .../Entities/Portfolio.cs | 1 - .../Entities/Programme.cs | 1 - PostFundManagement.Domain/Entities/Project.cs | 1 - PostFundManagement.Domain/Entities/Risk.cs | 1 - PostFundManagement.Domain/Entities/Rule.cs | 1 - .../Entities/SiteVisit.cs | 1 - PostFundManagement.Domain/Entities/Tenant.cs | 4 +- PostFundManagement.Domain/Entities/User.cs | 2 - PostFundManagement.Domain/Enums.cs | 28 +- .../Health/PostgresHealthCheck.cs | 2 - .../Health/QuartzHealthCheck.cs | 2 - .../Models/Security/Contracts.cs | 6 +- .../PostFundManagement.Domain.csproj | 353 +++++++++--------- .../Factories/ApplicationDbContextFactory.cs | 2 - .../DataProtectionDbContextFactory.cs | 2 - .../PostFundManagement.Infrastructure.csproj | 5 + .../Security/SkorubaUserService.cs | 1 - 53 files changed, 209 insertions(+), 254 deletions(-) delete mode 100644 PostFundManagement.Application/Abstractions/Services/IToolService.cs diff --git a/PostFundManagement.Api/PostFundManagement.Api.csproj b/PostFundManagement.Api/PostFundManagement.Api.csproj index 26284aa..ef0be7e 100644 --- a/PostFundManagement.Api/PostFundManagement.Api.csproj +++ b/PostFundManagement.Api/PostFundManagement.Api.csproj @@ -90,7 +90,7 @@ - + diff --git a/PostFundManagement.Application/Abstractions/Services/IToolService.cs b/PostFundManagement.Application/Abstractions/Services/IToolService.cs deleted file mode 100644 index c848b6f..0000000 --- a/PostFundManagement.Application/Abstractions/Services/IToolService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace PostFundManagement.Application.Abstractions.Services; - -public interface IToolService -{ - Task> EncodeLong(long id, CancellationToken cancellationToken); -} diff --git a/PostFundManagement.Application/Extensions/Postgres.cs b/PostFundManagement.Application/Extensions/Postgres.cs index ef640a8..4fa1a83 100644 --- a/PostFundManagement.Application/Extensions/Postgres.cs +++ b/PostFundManagement.Application/Extensions/Postgres.cs @@ -1,5 +1,4 @@ using PostFundManagement.Infrastructure.Database; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; diff --git a/PostFundManagement.Application/Extensions/Quartz.cs b/PostFundManagement.Application/Extensions/Quartz.cs index 8ae2777..3dbdb82 100644 --- a/PostFundManagement.Application/Extensions/Quartz.cs +++ b/PostFundManagement.Application/Extensions/Quartz.cs @@ -1,6 +1,5 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Quartz; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; diff --git a/PostFundManagement.Application/Extensions/S3.cs b/PostFundManagement.Application/Extensions/S3.cs index 89d39d8..38a5e0a 100644 --- a/PostFundManagement.Application/Extensions/S3.cs +++ b/PostFundManagement.Application/Extensions/S3.cs @@ -1,6 +1,5 @@ using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; diff --git a/PostFundManagement.Application/Extensions/Security.cs b/PostFundManagement.Application/Extensions/Security.cs index 5e6545a..434220b 100644 --- a/PostFundManagement.Application/Extensions/Security.cs +++ b/PostFundManagement.Application/Extensions/Security.cs @@ -5,7 +5,6 @@ using PostFundManagement.Domain.Configuration.Security; using PostFundManagement.Domain.Extensions; using PostFundManagement.Infrastructure.Database; using PostFundManagement.Infrastructure.Security; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Extensions; diff --git a/PostFundManagement.Application/Filters/ActiveUserFilter.cs b/PostFundManagement.Application/Filters/ActiveUserFilter.cs index dba5679..19c3e0c 100644 --- a/PostFundManagement.Application/Filters/ActiveUserFilter.cs +++ b/PostFundManagement.Application/Filters/ActiveUserFilter.cs @@ -1,6 +1,4 @@ using PostFundManagement.Application.Abstractions.Services; -using static PostFundManagement.Application.Extensions.General; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Filters; diff --git a/PostFundManagement.Application/Filters/UserRoleFilter.cs b/PostFundManagement.Application/Filters/UserRoleFilter.cs index ca54e14..55b0c99 100644 --- a/PostFundManagement.Application/Filters/UserRoleFilter.cs +++ b/PostFundManagement.Application/Filters/UserRoleFilter.cs @@ -1,6 +1,5 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Filters; diff --git a/PostFundManagement.Application/PostFundManagement.Application.csproj b/PostFundManagement.Application/PostFundManagement.Application.csproj index 44bdc83..96108ea 100644 --- a/PostFundManagement.Application/PostFundManagement.Application.csproj +++ b/PostFundManagement.Application/PostFundManagement.Application.csproj @@ -36,6 +36,12 @@ + + + + + + diff --git a/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs b/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs index ced8a19..a4d1300 100644 --- a/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs +++ b/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Communications; diff --git a/PostFundManagement.Application/Services/Communications/Records.cs b/PostFundManagement.Application/Services/Communications/Records.cs index 706df2f..93e340c 100644 --- a/PostFundManagement.Application/Services/Communications/Records.cs +++ b/PostFundManagement.Application/Services/Communications/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Communications; diff --git a/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs b/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs index 91f386d..3be2893 100644 --- a/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs +++ b/PostFundManagement.Application/Services/Evidence/EvidenceCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Evidence; diff --git a/PostFundManagement.Application/Services/Evidence/Records.cs b/PostFundManagement.Application/Services/Evidence/Records.cs index 7bfc003..c03a29f 100644 --- a/PostFundManagement.Application/Services/Evidence/Records.cs +++ b/PostFundManagement.Application/Services/Evidence/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Evidence; diff --git a/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs b/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs index 032afef..c229cd4 100644 --- a/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs +++ b/PostFundManagement.Application/Services/Execution/ExecutionCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Execution; diff --git a/PostFundManagement.Application/Services/Execution/Records.cs b/PostFundManagement.Application/Services/Execution/Records.cs index 81b466e..1f17eaa 100644 --- a/PostFundManagement.Application/Services/Execution/Records.cs +++ b/PostFundManagement.Application/Services/Execution/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Execution; diff --git a/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs b/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs index 030fcc7..8deb7fd 100644 --- a/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs +++ b/PostFundManagement.Application/Services/Governance/GovernanceCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Governance; diff --git a/PostFundManagement.Application/Services/Governance/Records.cs b/PostFundManagement.Application/Services/Governance/Records.cs index d37e3e1..a8f3d7c 100644 --- a/PostFundManagement.Application/Services/Governance/Records.cs +++ b/PostFundManagement.Application/Services/Governance/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Governance; diff --git a/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs b/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs index e8c3bb1..ef14bed 100644 --- a/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs +++ b/PostFundManagement.Application/Services/Grants/GrantsCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Grants; diff --git a/PostFundManagement.Application/Services/Grants/Records.cs b/PostFundManagement.Application/Services/Grants/Records.cs index c8f5ebe..fbe18c5 100644 --- a/PostFundManagement.Application/Services/Grants/Records.cs +++ b/PostFundManagement.Application/Services/Grants/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Grants; diff --git a/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs b/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs index 392f91b..9f7adbf 100644 --- a/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs +++ b/PostFundManagement.Application/Services/Projects/ProjectCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Projects; diff --git a/PostFundManagement.Application/Services/Projects/Records.cs b/PostFundManagement.Application/Services/Projects/Records.cs index 17fba04..87cf9ed 100644 --- a/PostFundManagement.Application/Services/Projects/Records.cs +++ b/PostFundManagement.Application/Services/Projects/Records.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Projects; diff --git a/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs b/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs index 7aede7c..1b24434 100644 --- a/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs +++ b/PostFundManagement.Application/Services/Shared/GeneralS3Service.cs @@ -1,6 +1,5 @@ using PostFundManagement.Application.Abstractions.Services; using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Shared; diff --git a/PostFundManagement.Application/Services/Users/UserCacheService.cs b/PostFundManagement.Application/Services/Users/UserCacheService.cs index 9c25c7b..312383b 100644 --- a/PostFundManagement.Application/Services/Users/UserCacheService.cs +++ b/PostFundManagement.Application/Services/Users/UserCacheService.cs @@ -3,7 +3,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Application.Services.Users; diff --git a/PostFundManagement.Domain/Entities/Activity.cs b/PostFundManagement.Domain/Entities/Activity.cs index b2c059f..a6fe592 100644 --- a/PostFundManagement.Domain/Entities/Activity.cs +++ b/PostFundManagement.Domain/Entities/Activity.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/AuditLog.cs b/PostFundManagement.Domain/Entities/AuditLog.cs index cb70df6..4febf16 100644 --- a/PostFundManagement.Domain/Entities/AuditLog.cs +++ b/PostFundManagement.Domain/Entities/AuditLog.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] diff --git a/PostFundManagement.Domain/Entities/Beneficiary.cs b/PostFundManagement.Domain/Entities/Beneficiary.cs index e9e2d0f..9737fd4 100644 --- a/PostFundManagement.Domain/Entities/Beneficiary.cs +++ b/PostFundManagement.Domain/Entities/Beneficiary.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Budget.cs b/PostFundManagement.Domain/Entities/Budget.cs index 7123756..099946d 100644 --- a/PostFundManagement.Domain/Entities/Budget.cs +++ b/PostFundManagement.Domain/Entities/Budget.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/ChangeRequest.cs b/PostFundManagement.Domain/Entities/ChangeRequest.cs index a95c84a..c885093 100644 --- a/PostFundManagement.Domain/Entities/ChangeRequest.cs +++ b/PostFundManagement.Domain/Entities/ChangeRequest.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/ComplianceItem.cs b/PostFundManagement.Domain/Entities/ComplianceItem.cs index e67faa2..9660313 100644 --- a/PostFundManagement.Domain/Entities/ComplianceItem.cs +++ b/PostFundManagement.Domain/Entities/ComplianceItem.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Indicator.cs b/PostFundManagement.Domain/Entities/Indicator.cs index 1215875..b31d03e 100644 --- a/PostFundManagement.Domain/Entities/Indicator.cs +++ b/PostFundManagement.Domain/Entities/Indicator.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Instrument.cs b/PostFundManagement.Domain/Entities/Instrument.cs index 85453ed..6adf209 100644 --- a/PostFundManagement.Domain/Entities/Instrument.cs +++ b/PostFundManagement.Domain/Entities/Instrument.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Issue.cs b/PostFundManagement.Domain/Entities/Issue.cs index 47c132a..48be6f9 100644 --- a/PostFundManagement.Domain/Entities/Issue.cs +++ b/PostFundManagement.Domain/Entities/Issue.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Milestone.cs b/PostFundManagement.Domain/Entities/Milestone.cs index 85a9581..142a00b 100644 --- a/PostFundManagement.Domain/Entities/Milestone.cs +++ b/PostFundManagement.Domain/Entities/Milestone.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Notification.cs b/PostFundManagement.Domain/Entities/Notification.cs index 1da94a1..7ce906b 100644 --- a/PostFundManagement.Domain/Entities/Notification.cs +++ b/PostFundManagement.Domain/Entities/Notification.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Organisation.cs b/PostFundManagement.Domain/Entities/Organisation.cs index fce062b..8d0df3a 100644 --- a/PostFundManagement.Domain/Entities/Organisation.cs +++ b/PostFundManagement.Domain/Entities/Organisation.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] diff --git a/PostFundManagement.Domain/Entities/Outcome.cs b/PostFundManagement.Domain/Entities/Outcome.cs index fbd8358..8991a8a 100644 --- a/PostFundManagement.Domain/Entities/Outcome.cs +++ b/PostFundManagement.Domain/Entities/Outcome.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Portfolio.cs b/PostFundManagement.Domain/Entities/Portfolio.cs index 76643b2..34cee15 100644 --- a/PostFundManagement.Domain/Entities/Portfolio.cs +++ b/PostFundManagement.Domain/Entities/Portfolio.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Programme.cs b/PostFundManagement.Domain/Entities/Programme.cs index 7f5f25f..2388bc8 100644 --- a/PostFundManagement.Domain/Entities/Programme.cs +++ b/PostFundManagement.Domain/Entities/Programme.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Project.cs b/PostFundManagement.Domain/Entities/Project.cs index fb4612f..1a5c962 100644 --- a/PostFundManagement.Domain/Entities/Project.cs +++ b/PostFundManagement.Domain/Entities/Project.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Risk.cs b/PostFundManagement.Domain/Entities/Risk.cs index 0591cc6..7c94d1f 100644 --- a/PostFundManagement.Domain/Entities/Risk.cs +++ b/PostFundManagement.Domain/Entities/Risk.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Rule.cs b/PostFundManagement.Domain/Entities/Rule.cs index e4ae1b4..c4688eb 100644 --- a/PostFundManagement.Domain/Entities/Rule.cs +++ b/PostFundManagement.Domain/Entities/Rule.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/SiteVisit.cs b/PostFundManagement.Domain/Entities/SiteVisit.cs index eee8e43..ad2b6ed 100644 --- a/PostFundManagement.Domain/Entities/SiteVisit.cs +++ b/PostFundManagement.Domain/Entities/SiteVisit.cs @@ -1,5 +1,4 @@ using PostFundManagement.Domain.Abstractions; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Domain.Entities; diff --git a/PostFundManagement.Domain/Entities/Tenant.cs b/PostFundManagement.Domain/Entities/Tenant.cs index 6bab5aa..58582dc 100644 --- a/PostFundManagement.Domain/Entities/Tenant.cs +++ b/PostFundManagement.Domain/Entities/Tenant.cs @@ -1,6 +1,4 @@ -using static PostFundManagement.Domain.Extensions.Constants; - -namespace PostFundManagement.Domain.Entities; +namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] public class Tenant : Models.Tenant diff --git a/PostFundManagement.Domain/Entities/User.cs b/PostFundManagement.Domain/Entities/User.cs index 270427f..00be259 100644 --- a/PostFundManagement.Domain/Entities/User.cs +++ b/PostFundManagement.Domain/Entities/User.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Entities; [EntityTypeConfiguration] diff --git a/PostFundManagement.Domain/Enums.cs b/PostFundManagement.Domain/Enums.cs index 7482db7..bb75ca1 100644 --- a/PostFundManagement.Domain/Enums.cs +++ b/PostFundManagement.Domain/Enums.cs @@ -9,7 +9,7 @@ public enum EmailStatuses : int Disconnected = 4, TooManyConnections = 5, ConnectionAborted = 6, - Success = 7 + Success = 7, } public enum NotificationStatus : int @@ -22,7 +22,7 @@ public enum NotificationStatus : int Read = 6, Failed = 7, Cancelled = 8, - Bounced = 9 + Bounced = 9, } public enum NotificationPlatform : int @@ -35,7 +35,7 @@ public enum NotificationPlatform : int Teams = 6, Slack = 7, Webhook = 8, - Other = 99 + Other = 99, } public enum EvidenceType : int @@ -51,7 +51,7 @@ public enum EvidenceType : int ProcurementDocument = 9, TechnicalSpecificationOrDesign = 10, VideoRecording = 11, - Other = 99 + Other = 99, } public enum ProjectType : int @@ -66,7 +66,7 @@ public enum ProjectType : int SocialImpactAndCommunityDevelopment = 8, TechnologyTransferAndAdoption = 9, Innovation = 10, - Other = 99 + Other = 99, } public enum IndustrySector : int @@ -88,7 +88,7 @@ public enum IndustrySector : int RetailAndConsumerGoods = 15, TourismAndHospitality = 16, WaterAndSanitation = 17, - Other = 99 + Other = 99, } public enum OrganisationType : int @@ -132,7 +132,7 @@ public enum OrganisationType : int // Consortium & Special Vehicles Consortium = 26, // Unincorporated joint venture - SpecialPurposeVehicle = 27 // SPV / Joint Venture Entity + SpecialPurposeVehicle = 27, // SPV / Joint Venture Entity } public enum Priority : int @@ -140,7 +140,7 @@ public enum Priority : int Low = 1, Medium = 2, High = 3, - Critical = 4 + Critical = 4, } public enum UnitOfMeasure : int @@ -153,7 +153,7 @@ public enum UnitOfMeasure : int Volume = 6, DurationDays = 7, DurationMonths = 8, - Ratio = 9 + Ratio = 9, } public enum ContractStatus : int { @@ -162,7 +162,7 @@ public enum ContractStatus : int Active = 3, Expired = 4, Terminated = 5, - Amended = 6 + Amended = 6, } public enum RiskLikelihood : int @@ -171,7 +171,7 @@ public enum RiskLikelihood : int Unlikely = 2, Possible = 3, Likely = 4, - AlmostCertain = 5 + AlmostCertain = 5, } public enum RiskImpact : int @@ -180,7 +180,7 @@ public enum RiskImpact : int Minor = 2, Moderate = 3, Major = 4, - Critical = 5 + Critical = 5, } public enum ApprovalStatus : int @@ -189,12 +189,12 @@ public enum ApprovalStatus : int Review = 2, Approved = 3, Rejected = 4, - Removed = 5 + Removed = 5, } public enum ActivityStatus : int { Active = 1, Inactive = 2, - Disabled = 3 + Disabled = 3, } \ No newline at end of file diff --git a/PostFundManagement.Domain/Health/PostgresHealthCheck.cs b/PostFundManagement.Domain/Health/PostgresHealthCheck.cs index 39b58ce..003572f 100644 --- a/PostFundManagement.Domain/Health/PostgresHealthCheck.cs +++ b/PostFundManagement.Domain/Health/PostgresHealthCheck.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Health; public sealed class PostgresHealthCheck(IConfiguration configuration) : IHealthCheck diff --git a/PostFundManagement.Domain/Health/QuartzHealthCheck.cs b/PostFundManagement.Domain/Health/QuartzHealthCheck.cs index e66b880..78090a4 100644 --- a/PostFundManagement.Domain/Health/QuartzHealthCheck.cs +++ b/PostFundManagement.Domain/Health/QuartzHealthCheck.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Domain.Health; public sealed class QuartzHealthCheck(ISchedulerFactory schedulerFactory) : IHealthCheck diff --git a/PostFundManagement.Domain/Models/Security/Contracts.cs b/PostFundManagement.Domain/Models/Security/Contracts.cs index bfbf504..8c8588f 100644 --- a/PostFundManagement.Domain/Models/Security/Contracts.cs +++ b/PostFundManagement.Domain/Models/Security/Contracts.cs @@ -6,10 +6,10 @@ public sealed record UpdateUserRequest(string Id, string UserName, string Email, public sealed record Claim(string ClaimType, string ClaimValue, int? ClaimId = null); -public record ClaimsResponse(int TotalCount, int PageSize, ICollection Claims); +public sealed record ClaimsResponse(int TotalCount, int PageSize, ICollection Claims); public sealed record UserResponse(string Id, string UserName, string Email, bool IsLockedOut, bool LockoutEnabled); -public record Role(string Id, string Name); +public sealed record Role(string Id, string Name); -public record RolesResponse(int TotalCount, int PageSize, ICollection Roles); \ No newline at end of file +public sealed record RolesResponse(int TotalCount, int PageSize, ICollection Roles); \ No newline at end of file diff --git a/PostFundManagement.Domain/PostFundManagement.Domain.csproj b/PostFundManagement.Domain/PostFundManagement.Domain.csproj index e1690af..80faa44 100644 --- a/PostFundManagement.Domain/PostFundManagement.Domain.csproj +++ b/PostFundManagement.Domain/PostFundManagement.Domain.csproj @@ -25,205 +25,210 @@ - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - + + + - - + + - - - - - - + + + + + + - - + + - - - - + + + + - - - - + + + + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + - - - + + + - - - - - - - + + + + + + + - - - + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + - - - - - - - - + + + + + + + + - - - - - - - + + + + + + + - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - - - - - - - + + + + + + + - - - - - - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs b/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs index 6046775..eae18cf 100644 --- a/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs +++ b/PostFundManagement.Infrastructure/Database/Factories/ApplicationDbContextFactory.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Infrastructure.Database.Factories; public sealed partial class ApplicationDbContextFactory : IDesignTimeDbContextFactory diff --git a/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs b/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs index b54ff53..8ea22a5 100644 --- a/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs +++ b/PostFundManagement.Infrastructure/Database/Factories/DataProtectionDbContextFactory.cs @@ -1,5 +1,3 @@ -using static PostFundManagement.Domain.Extensions.Constants; - namespace PostFundManagement.Infrastructure.Database.Factories; public sealed class DataProtectionDbContextFactory : IDesignTimeDbContextFactory diff --git a/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj b/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj index 4d741b3..6451b3a 100644 --- a/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj +++ b/PostFundManagement.Infrastructure/PostFundManagement.Infrastructure.csproj @@ -34,6 +34,11 @@ + + + + + diff --git a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs index 8389656..1def22d 100644 --- a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs +++ b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs @@ -1,7 +1,6 @@ using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Models.Security; -using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Infrastructure.Security; From 2ee7a49122be6f336ebb47bffe584db900746973 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 10 Oct 2026 10:12:13 +0200 Subject: [PATCH 03/10] Added user management endpoints --- .../GetTenantOrganisationsEndpoint.cs | 2 +- .../Endpoints/Users/AddUserClaimEndpoint.cs | 35 ++- .../Endpoints/Users/AddUserRoleEndpoint.cs | 34 ++- .../Endpoints/Users/CreateUserEndpoint.cs | 29 ++- .../Users/DeleteUserClaimEndpoint.cs | 35 ++- .../Endpoints/Users/DeleteUserRoleEndpoint.cs | 33 ++- .../Endpoints/Users/GetSystemRolesEndpoint.cs | 34 ++- .../Endpoints/Users/GetUserClaimsEndpoint.cs | 35 ++- .../Endpoints/Users/GetUserEndpoint.cs | 4 +- .../Endpoints/Users/GetUserRolesEndpoint.cs | 34 ++- .../Endpoints/Users/LogUserOutEndpoint.cs | 33 ++- .../Endpoints/Users/SetUserLockoutEndpoint.cs | 33 ++- .../Abstractions/Services/IUserService.cs | 40 +++- .../Extensions/Security.cs | 5 +- .../Services/Users/UserCacheService.cs | 106 ++++++++- .../Services/Users/UserService.cs | 210 +++++++++++++++++- .../Abstractions/ISkorubaUserService.cs | 9 +- .../Models/Security/Contracts.cs | 11 +- .../Security/SkorubaUserService.cs | 6 +- 19 files changed, 688 insertions(+), 40 deletions(-) diff --git a/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs b/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs index 80dc27c..70a3e62 100644 --- a/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Governance/GetTenantOrganisationsEndpoint.cs @@ -1,9 +1,9 @@ using PostFundManagement.Application.Abstractions.Services; using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; -using PostFundManagement.Domain.Entities; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models; namespace PostFundManagement.Api.Endpoints.Governance; diff --git a/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs index ace3d84..4cc6cdb 100644 --- a/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/AddUserClaimEndpoint.cs @@ -1,5 +1,36 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; -public class AddUserClaimEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class AddUserClaimEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPatch("api/users/user/claims", async (AddUserClaimRequest request, HttpContext context, + IUserService userService, CancellationToken cancellationToken = default) => + await userService.AddUserClaimAsync(request, userId: context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Adds a claim to a user") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(AddUserClaimEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs index 489399e..31109ec 100644 --- a/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs @@ -1,5 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class AddUserRoleEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class AddUserRoleEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPatch("api/users/{userId:Guid}/roles/{roleId}", async (Guid userId, string roleId, HttpContext context, + IUserService userService, CancellationToken cancellationToken = default) => + await userService.AddUserRoleAsync(userId, roleId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Adds a role to a user") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(AddUserRoleEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs index e994f7e..520b95d 100644 --- a/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/CreateUserEndpoint.cs @@ -1,4 +1,9 @@ -using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; namespace PostFundManagement.Api.Endpoints.Users; @@ -7,6 +12,26 @@ public sealed class CreateUserEndpoint : IEndpoint { public void Map(IEndpointRouteBuilder builder) { - throw new NotImplementedException(); + builder.MapPost("/api/users/{tenantId}/{idNumber}", async (string tenantId, string idNumber, CreateUserRequest request, HttpContext context, IUserService userService, + CancellationToken cancellationToken = default) => + await userService.CreateUserAsync(tenantId, idNumber, request, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.Forbid(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Creates a new user in the system") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(CreateUserEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status403Forbidden) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); } } diff --git a/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs index c96246d..fd8d4fa 100644 --- a/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/DeleteUserClaimEndpoint.cs @@ -1,6 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class DeleteUserClaimEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class DeleteUserClaimEndpoint : IEndpoint { - + public void Map(IEndpointRouteBuilder builder) + { + builder.MapDelete("api/users/{targetUserId:Guid}/claims/{claimId}", async (string claimId, Guid targetUserId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.DeleteUserClaimAsync(claimIdHash: claimId, targetUserId: targetUserId, userId: context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.Forbid(), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Deletes a claim from a user") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(DeleteUserClaimEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs index e756806..4977002 100644 --- a/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs @@ -1,5 +1,34 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class DeleteUserRoleEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class DeleteUserRoleEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapDelete("api/users/{userId:Guid}/roles/{roleId}", async (Guid userId, string roleId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.DeleteUserRoleAsync(userId, roleId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Delete user role") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(DeleteUserRoleEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs index fd50ffc..d289bc5 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetSystemRolesEndpoint.cs @@ -1,5 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; -public class GetSystemRolesEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetSystemRolesEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/system/roles", async (HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetSystemRolesAsync(context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var roles } => Results.Ok(roles), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get system roles") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetSystemRolesEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs index d425540..4a2d4d4 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUserClaimsEndpoint.cs @@ -1,6 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using Claim = PostFundManagement.Domain.Models.Security.Claim; -public class GetUserClaimsEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetUserClaimsEndpoint : IEndpoint { - + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/{userId:Guid}/claims", async (Guid userId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetUserClaimsAsync(userId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var claims } => Results.Ok(claims), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get user claims") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetUserClaimsEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs index fde821b..43749cf 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUserEndpoint.cs @@ -17,7 +17,7 @@ public sealed class GetUserEndpoint : IEndpoint await service.GetUserAsync(userId, cancellationToken) switch { { IsSuccess: true, Value: var user } => Results.Ok(user), - var r when r.HasError() => Results.NotFound(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), var r => Results.InternalServerError(r.Errors.ToProblems()) }) .WithDescription("Gets the metadata of a single user.") @@ -25,8 +25,8 @@ public sealed class GetUserEndpoint : IEndpoint .WithName(typeof(GetUserEndpoint).ToEndpointName()) .MapToApiVersion(new ApiVersion(1)) .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) .Produces(StatusCodes.Status500InternalServerError) .WithTags(EndpointTags.Users) .CacheOutput(); diff --git a/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs index 3eb3739..367de1d 100644 --- a/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/GetUserRolesEndpoint.cs @@ -1,5 +1,35 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models.Security; -public class GetUserRolesEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetUserRolesEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/{userId:Guid}/roles", async (Guid userId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetUserRolesAsync(userId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var roles } => Results.Ok(roles), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get user roles") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetUserRolesEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs index d9f9905..1d00f5a 100644 --- a/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/LogUserOutEndpoint.cs @@ -1,5 +1,34 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class LogUserOutEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class LogUserOutEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPut("api/users/{userId:Guid}/session/logout", async (Guid userId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.LogoutUserAsync(userId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Logout user session") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(LogUserOutEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs index b8173d0..c58aac9 100644 --- a/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/SetUserLockoutEndpoint.cs @@ -1,5 +1,34 @@ -namespace PostFundManagement.Api.Endpoints.Users; +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; -public class SetUserLockoutEndpoint +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class SetUserLockoutEndpoint : IEndpoint { + public void Map(IEndpointRouteBuilder builder) + { + builder.MapPut("api/users/{userId:Guid}/session/lockout/{disable:bool}", async (Guid userId, bool disable, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.SetUserLockoutAsync(userId, context.GetUserId(), disable, cancellationToken) switch + { + { IsSuccess: true } => Results.Ok(), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Lock user session") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(SetUserLockoutEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } } diff --git a/PostFundManagement.Application/Abstractions/Services/IUserService.cs b/PostFundManagement.Application/Abstractions/Services/IUserService.cs index bb206cb..a6e7974 100644 --- a/PostFundManagement.Application/Abstractions/Services/IUserService.cs +++ b/PostFundManagement.Application/Abstractions/Services/IUserService.cs @@ -2,6 +2,7 @@ using PostFundManagement.Domain; using PostFundManagement.Domain.Attributes; using PostFundManagement.Domain.Models; +using PostFundManagement.Domain.Models.Security; namespace PostFundManagement.Application.Abstractions.Services; @@ -19,5 +20,42 @@ public interface IUserService Task UpdateUserStatusAsync(Guid userId, ActivityStatus status, CancellationToken cancellationToken = default); [Log] - Task> GetUserAsync(Guid userId, CancellationToken cancellationToken); + Task> GetUserAsync(Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task CreateUserAsync(string tenantIdHash, string idNumberHash, CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task AddUserClaimAsync(AddUserClaimRequest request, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task AddUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task DeleteUserClaimAsync(string claimIdHash, Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task SetUserLockoutAsync(Guid targetUserId, Guid userId, bool disable, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task LogoutUserAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + Task> GetUserRolesAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + Task> GetUserClaimsAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + + [Log] + Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task DeleteUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Application/Extensions/Security.cs b/PostFundManagement.Application/Extensions/Security.cs index 434220b..029c3dc 100644 --- a/PostFundManagement.Application/Extensions/Security.cs +++ b/PostFundManagement.Application/Extensions/Security.cs @@ -32,12 +32,15 @@ public static class Security client.ClientSecret = ClientSecret.Parse(authOptions.ClientSecret!); client.Scope = Duende.AccessTokenManagement.Scope.ParseOrDefault(authOptions.Scope); }); - + services.AddHttpClient(SkorubaHttpClient, client => { client.BaseAddress = new Uri(configuration.GetConnectionString("SkorubaApi")!); }).AddClientCredentialsTokenHandler(ClientCredentialsClientName.Parse(SkorubaCredentialClient)); + services.AddKeyedScoped(SkorubaHttpClient, (provider, key) => + provider.GetRequiredService()); + services.AddScoped(); services.AddScoped(); services.AddSingleton(); diff --git a/PostFundManagement.Application/Services/Users/UserCacheService.cs b/PostFundManagement.Application/Services/Users/UserCacheService.cs index 312383b..f4e5022 100644 --- a/PostFundManagement.Application/Services/Users/UserCacheService.cs +++ b/PostFundManagement.Application/Services/Users/UserCacheService.cs @@ -3,12 +3,54 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Models; +using PostFundManagement.Domain.Models.Security; +using Claim = PostFundManagement.Domain.Models.Security.Claim; namespace PostFundManagement.Application.Services.Users; -public sealed class UserCacheService(UserService service, IDistributedCache cache, +public sealed class UserCacheService(UserService service, IDistributedCache cache, IFeatureManager featureManager) : ServiceCacheBase, IUserService { + public async Task AddUserClaimAsync(AddUserClaimRequest request, Guid userId, CancellationToken cancellationToken = default) => + await service.AddUserClaimAsync(request, userId, cancellationToken); + + public async Task AddUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + await service.AddUserRoleAsync(targetUserId, roleId, userId, cancellationToken); + + public async Task CreateUserAsync(string tenantIdHash, string idNumberHash, CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => + await service.CreateUserAsync(tenantIdHash, idNumberHash, request, userId, cancellationToken); + + public async Task DeleteUserClaimAsync(string claimIdHash, Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await service.DeleteUserClaimAsync(claimIdHash, targetUserId, userId, cancellationToken); + + public async Task DeleteUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + await service.DeleteUserRoleAsync(targetUserId, roleId, userId, cancellationToken); + + public async Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetSystemRolesAsync(userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getsystemroles-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var rolesResult = await service.GetSystemRolesAsync(userId, cancellationToken); + + if (rolesResult.IsFailed) return rolesResult; + + await cache.SetStringAsync(cacheKey, rolesResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return rolesResult; + } + + return Result.Ok(cached.FromJson()); + })); + public async Task> GetUserAsync(Guid userId, CancellationToken cancellationToken) => await Result.Try((Func>>)(async () => { @@ -19,7 +61,7 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach var cached = await cache.GetStringAsync(cacheKey, cancellationToken); - if(string.IsNullOrWhiteSpace(cached)) + if (string.IsNullOrWhiteSpace(cached)) { var userResult = await service.GetUserAsync(userId, cancellationToken); @@ -33,6 +75,56 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach return Result.Ok(cached.FromJson()); })); + public async Task> GetUserClaimsAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetUserClaimsAsync(targetUserId, userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getuserclaims-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var claimsResult = await service.GetUserClaimsAsync(targetUserId, userId, cancellationToken); + + if (claimsResult.IsFailed) return claimsResult; + + await cache.SetStringAsync(cacheKey, claimsResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return claimsResult; + } + + return Result.Ok(cached.FromJson()); + })); + + public async Task> GetUserRolesAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetUserRolesAsync(targetUserId, userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getuserroles-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var rolesResult = await service.GetUserRolesAsync(targetUserId, userId, cancellationToken); + + if (rolesResult.IsFailed) return rolesResult; + + await cache.SetStringAsync(cacheKey, rolesResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return rolesResult; + } + + return Result.Ok(cached.FromJson()); + })); + public async Task> GetUsersAsync(Pagination pagination, UserFilterRequest request, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { @@ -50,7 +142,7 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach if (usersResult.IsFailed) return usersResult; - await cache.SetStringAsync(cacheKey, usersResult.Value.ToJson(), + await cache.SetStringAsync(cacheKey, usersResult.Value.ToJson(), cacheOptions, cancellationToken); return usersResult; @@ -59,9 +151,15 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach return Result.Ok(cached.FromJson()); })); + public async Task LogoutUserAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await service.LogoutUserAsync(targetUserId, userId, cancellationToken); + + public async Task SetUserLockoutAsync(Guid targetUserId, Guid userId, bool disable, CancellationToken cancellationToken = default) => + await service.SetUserLockoutAsync(targetUserId, userId, disable, cancellationToken); + public async Task SyncUserAsync(Guid userId, string email, string role, CancellationToken cancellationToken = default) => await service.SyncUserAsync(userId, email, role, cancellationToken); - + public async Task UpdateUserStatusAsync(Guid userId, ActivityStatus status, CancellationToken cancellationToken = default) => await service.UpdateUserStatusAsync(userId, status, cancellationToken); } diff --git a/PostFundManagement.Application/Services/Users/UserService.cs b/PostFundManagement.Application/Services/Users/UserService.cs index 755ddc6..76527f9 100644 --- a/PostFundManagement.Application/Services/Users/UserService.cs +++ b/PostFundManagement.Application/Services/Users/UserService.cs @@ -1,14 +1,18 @@ using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Domain.Errors; using PostFundManagement.Domain.Extensions; using PostFundManagement.Domain.Models; +using PostFundManagement.Domain.Models.Security; using PostFundManagement.Infrastructure.Database; +using Claim = PostFundManagement.Domain.Models.Security.Claim; namespace PostFundManagement.Application.Services.Users; -public sealed class UserService(IDbContextFactory contextFactory, ITenantContextService tenantContext) : IUserService +public sealed class UserService(IDbContextFactory contextFactory, ITenantContextService tenantContext, + ISkorubaUserService skorubaService, HashService hashService) : IUserService { public async Task SyncUserAsync(Guid userId, string email, string role, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => @@ -113,4 +117,208 @@ public sealed class UserService(IDbContextFactory contextF return Result.FailIf(tenantUser == null, NotFoundError.Create("User not found.")) .ToResult(tenantUser!.User?.Map()!); })); + + public async Task CreateUserAsync(string tenantIdHash, string idNumberHash, CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var tenantIdHashDecode = hashService.DecodeLongIdHash(tenantIdHash); + + if (tenantIdHashDecode.IsFailed) + return Result.Fail(IdDecodeError.Create() + .CausedBy(tenantIdHashDecode.Errors)); + + var tenantId = tenantIdHashDecode.Value; + + var idNumberHashDecode = await hashService.DecodeHexHash(idNumberHash); + + if (idNumberHashDecode.IsFailed) + return Result.Fail(IdDecodeError.Create() + .CausedBy(idNumberHashDecode.Errors)); + + var idNumber = idNumberHashDecode.Value.Trim(); + + var email = request.Email?.Trim().ToLowerInvariant(); + + if (string.IsNullOrWhiteSpace(email)) + return Result.Fail(ValidationError.Create("Email is required.")); + + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + if (await context.Users.AnyAsync(u => u.Email == email, cancellationToken)) + return Result.Fail(ValidationError.Create("User with this email already exists.")); + + var createUserResult = await skorubaService.CreateUserAsync(request, userId, cancellationToken); + + if (createUserResult.IsFailed) + return Result.Fail(CreateError.Create("Failed to create user.")); + + var newUserId = Guid.Parse(createUserResult.Value.Trim()); + + var availableRolesResult = await skorubaService.GetAvailableRolesAsync(cancellationToken: cancellationToken); + + if (availableRolesResult.IsFailed) + return Result.Fail(NotFoundError.Create("Failed to retrieve available roles.")); + + var defaultRole = availableRolesResult.Value.FirstOrDefault(r => r.Name == "Contributor"); + + if (defaultRole == null) + return Result.Fail(NotFoundError.Create("Role 'Contributor' not found.")); + + var roleAssignmentResult = await skorubaService.AddRoleAsync(newUserId, defaultRole.Id, cancellationToken); + + if (roleAssignmentResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to assign role to user.")); + + var newUser = context.Users.Add(new Domain.Entities.User + { + Id = newUserId, + Email = email, + Status = ActivityStatus.Active, + LastLoginAt = DateTime.UtcNow, + IdNumber = idNumber, + Role = defaultRole.Name, + }); + + context.TenantUsers.Add(new Domain.Entities.TenantUser + { + CreatedAt = DateTime.UtcNow, + CreatedBy = userId, + Status = ActivityStatus.Active, + TenantId = tenantId, + UserId = newUserId, + }); + + return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create user, contact support")); + })); + + public async Task DeleteUserClaimAsync(string claimIdHash, Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var claimIdHashDecode = hashService.DecodeIntIdHash(claimIdHash); + + if (claimIdHashDecode.IsFailed) + return Result.Fail(IdDecodeError.Create() + .CausedBy(claimIdHashDecode.Errors)); + + var claimId = claimIdHashDecode.Value; + + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + if (!await context.Users.AnyAsync(u => u.Id == targetUserId, cancellationToken)) + return Result.Fail(NotFoundError.Create("User not found.")); + + var claimDeleteResult = await skorubaService.RemoveClaimAsync(targetUserId, claimId, cancellationToken); + + return Result.OkIf(claimDeleteResult.IsSuccess, ValidationError.Create("Failed to delete user claim.") + .CausedBy(claimDeleteResult.Errors)); + })); + + public async Task SetUserLockoutAsync(Guid targetUserId, Guid userId, bool disable, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var lockoutResult = await skorubaService.SetUserLockoutAsync(targetUserId, disable, cancellationToken); + + if(lockoutResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to set user lockout.") + .CausedBy(lockoutResult.Errors)); + + var changedTotal = await context.Users.Where(f => f.Id == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Status, disable ? ActivityStatus.Disabled : ActivityStatus.Active), cancellationToken); + + changedTotal += await context.TenantUsers.Where(f => f.UserId == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Status, disable ? ActivityStatus.Disabled : ActivityStatus.Active), cancellationToken); + + return Result.OkIf(lockoutResult.IsSuccess && changedTotal > 0, ValidationError.Create("Failed to set user lockout.") + .CausedBy(lockoutResult.Errors)); + })); + + public async Task LogoutUserAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var logoutResult = await skorubaService.InvalidateUserSessionAsync(targetUserId, cancellationToken); + + return Result.OkIf(logoutResult.IsSuccess, ValidationError.Create("Failed to logout user.") + .CausedBy(logoutResult.Errors)); + })); + + public async Task> GetUserRolesAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetUserRolesAsync(targetUserId, cancellationToken: cancellationToken))); + + public async Task> GetUserClaimsAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetUserClaimsAsync(targetUserId, cancellationToken: cancellationToken))); + + public async Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetAvailableRolesAsync(cancellationToken: cancellationToken))); + + public async Task DeleteUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var changedTotal = await context.Users.Where(f => f.Id == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Role, string.Empty), cancellationToken); + + var roleDeleteResult = await skorubaService.RemoveRoleAsync(targetUserId, roleId, cancellationToken); + + return Result.OkIf(roleDeleteResult.IsSuccess && changedTotal > 0, ValidationError.Create("Failed to delete user role.") + .CausedBy(roleDeleteResult.Errors)); + })); + + public async Task AddUserClaimAsync(AddUserClaimRequest request, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var addClaimResult = await skorubaService.AddClaimAsync(request.UserId, request.ClaimType, request.ClaimValue, cancellationToken); + + return Result.OkIf(addClaimResult.IsSuccess, ValidationError.Create("Failed to add user claim.") + .CausedBy(addClaimResult.Errors)); + })); + + public async Task AddUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var userRolesResult = await skorubaService.GetUserRolesAsync(targetUserId, cancellationToken: cancellationToken); + + if (userRolesResult.IsFailed) + return Result.Fail(NotFoundError.Create("Failed to retrieve user roles.") + .CausedBy(userRolesResult.Errors)); + + foreach (var role in userRolesResult.Value) + { + var deleteRoleResult = await skorubaService.RemoveRoleAsync(targetUserId, role.Id, cancellationToken); + + if (deleteRoleResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to remove existing user role.") + .CausedBy(deleteRoleResult.Errors)); + } + + var roleAddResult = await skorubaService.AddRoleAsync(targetUserId, roleId, cancellationToken); + + if(roleAddResult.IsFailed) + return Result.Fail(UpdateError.Create("Failed to add user role.") + .CausedBy(roleAddResult.Errors)); + + var systemRoles = await skorubaService.GetAvailableRolesAsync(cancellationToken: cancellationToken); + + if (systemRoles.IsFailed) + return Result.Fail(NotFoundError.Create("Failed to retrieve system roles.") + .CausedBy(systemRoles.Errors)); + + var targetRole = systemRoles.Value.FirstOrDefault(r => r.Id == roleId); + + if (targetRole == null) + return Result.Fail(NotFoundError.Create("Role not found.")); + + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var changedTotal = await context.Users.Where(f => f.Id == targetUserId) + .ExecuteUpdateAsync(f => f.SetProperty(u => u.Role, targetRole.Name), cancellationToken); + + return Result.OkIf(roleAddResult.IsSuccess && changedTotal > 0, ValidationError.Create("Failed to add user role.") + .CausedBy(roleAddResult.Errors)); + })); } diff --git a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs index 8cf3968..3294d03 100644 --- a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs +++ b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs @@ -7,7 +7,7 @@ public interface ISkorubaUserService { [Log] [Audit] - Task> CreateUserAsync(CreateUserRequest request, CancellationToken cancellationToken = default); + Task> CreateUserAsync(CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default); [Log] Task> GetUserAsync(Guid userId, CancellationToken cancellationToken = default); @@ -40,8 +40,11 @@ public interface ISkorubaUserService Task> GetAvailableRolesAsync(string? searchText = null, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); [Log] - Task> GetUserRolesAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + Task> GetUserRolesAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); [Log] - Task> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + + [Log] + Task InvalidateUserSessionAsync(Guid userId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Domain/Models/Security/Contracts.cs b/PostFundManagement.Domain/Models/Security/Contracts.cs index 8c8588f..e4d1260 100644 --- a/PostFundManagement.Domain/Models/Security/Contracts.cs +++ b/PostFundManagement.Domain/Models/Security/Contracts.cs @@ -1,8 +1,15 @@ -namespace PostFundManagement.Domain.Models.Security; +using System.ComponentModel.DataAnnotations; + +namespace PostFundManagement.Domain.Models.Security; + +public sealed record AddUserClaimRequest([Required] Guid UserId, + [Required] int ClaimId, + [Required][MaxLength(LabelLength)] string ClaimType, + [Required][MaxLength(LabelLength)] string ClaimValue); public sealed record CreateUserRequest(string UserName, string Email, string Password, bool EmailConfirmed = true, string? PhoneNumber = null, bool PhoneNumberConfirmed = false); -public sealed record UpdateUserRequest(string Id, string UserName, string Email, bool EmailConfirmed, string? PhoneNumber, bool PhoneNumberConfirmed, bool LockoutEnabled, DateTimeOffset? LockoutEnd, int AccessFailedCount, bool TwoFactorEnabled); +public sealed record UpdateUserRequest(string UserId, string UserName, string Email, bool EmailConfirmed, string? PhoneNumber, bool PhoneNumberConfirmed, bool LockoutEnabled, DateTimeOffset? LockoutEnd, int AccessFailedCount, bool TwoFactorEnabled); public sealed record Claim(string ClaimType, string ClaimValue, int? ClaimId = null); diff --git a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs index 1def22d..f070cfe 100644 --- a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs +++ b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs @@ -6,7 +6,7 @@ namespace PostFundManagement.Infrastructure.Security; public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClientFactory httpClientFactory) : ISkorubaUserService { - public async Task> CreateUserAsync(CreateUserRequest request, CancellationToken cancellationToken = default) => + public async Task> CreateUserAsync(CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var httpClient = httpClientFactory.CreateClient(); @@ -80,7 +80,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user claim.")); })); - public async Task> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => + public async Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var httpClient = httpClientFactory.CreateClient(); @@ -111,7 +111,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user role.")); })); - public async Task> GetUserRolesAsync(string userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => + public async Task> GetUserRolesAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var httpClient = httpClientFactory.CreateClient(); From 343f405982ff37e3c2c97dbe3c63ebd147473356 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 10 Oct 2026 11:11:23 +0200 Subject: [PATCH 04/10] Added consolidated applicant data retrieval endpoint --- .../GetIApplicantDataEndpoint.cs | 35 +++++++++++ .../Services/ICommunicationsService.cs | 3 + .../CommunicationsCacheService.cs | 22 +++++++ .../Communications/CommunicationsService.cs | 63 +++++++++++++++++-- .../Models/ApplicantData.cs | 16 +++++ 5 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 PostFundManagement.Api/Endpoints/Communications/GetIApplicantDataEndpoint.cs create mode 100644 PostFundManagement.Domain/Models/ApplicantData.cs diff --git a/PostFundManagement.Api/Endpoints/Communications/GetIApplicantDataEndpoint.cs b/PostFundManagement.Api/Endpoints/Communications/GetIApplicantDataEndpoint.cs new file mode 100644 index 0000000..9a83ce9 --- /dev/null +++ b/PostFundManagement.Api/Endpoints/Communications/GetIApplicantDataEndpoint.cs @@ -0,0 +1,35 @@ +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; +using PostFundManagement.Domain.Models; + +namespace PostFundManagement.Api.Endpoints.Communications; + +[ApiVersionTarget(1)] +public sealed class GetIApplicantDataEndpoint : IEndpoint +{ + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/communications/applicants/{applicantUserId:Guid}/all", async (Guid applicantUserId, + ICommunicationsService service, CancellationToken cancellationtToken = default ) => + await service.GetApplicantDataAsync(applicantUserId, cancellationtToken) switch + { + { IsSuccess: true, Value: var applicantData } => Results.Ok(applicantData), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()), + }) + .WithDescription("Gets an applicant's data") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetIApplicantDataEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Communications) + .CacheOutput(); + } +} diff --git a/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs b/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs index 23149ff..3eaf3e6 100644 --- a/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs +++ b/PostFundManagement.Application/Abstractions/Services/ICommunicationsService.cs @@ -33,4 +33,7 @@ public interface ICommunicationsService [Log] Task> GetNotificationAsync(string notificationIdHash, CancellationToken cancellationToken = default); + + [Log] + Task> GetApplicantDataAsync(Guid applicantUserId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs b/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs index a4d1300..8a185a4 100644 --- a/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs +++ b/PostFundManagement.Application/Services/Communications/CommunicationsCacheService.cs @@ -12,6 +12,28 @@ public sealed class CommunicationsCacheService(CommunicationsService service, ID public async Task CreateNotificationAsync(CreateNotificationRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.CreateNotificationAsync(request, userId, cancellationToken); + public async Task> GetApplicantDataAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetApplicantDataAsync(applicantUserId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getapplicantdata-{applicantUserId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var result = await service.GetApplicantDataAsync(applicantUserId, cancellationToken); + + if (result.IsFailed) return result; + + await cache.SetStringAsync(cacheKey, result.Value.ToJson(), cacheOptions, cancellationToken); + } + + return Result.Ok(cached!.FromJson()); + })); + public async Task> GetApplicantInviteAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { diff --git a/PostFundManagement.Application/Services/Communications/CommunicationsService.cs b/PostFundManagement.Application/Services/Communications/CommunicationsService.cs index 7151876..90958d2 100644 --- a/PostFundManagement.Application/Services/Communications/CommunicationsService.cs +++ b/PostFundManagement.Application/Services/Communications/CommunicationsService.cs @@ -9,7 +9,7 @@ using PostFundManagement.Infrastructure.Database; namespace PostFundManagement.Application.Services.Communications; -public sealed class CommunicationsService(IDbContextFactory contextFactory, +public sealed class CommunicationsService(IDbContextFactory contextFactory, HashService hashService, ITenantContextService tenantContext) : ICommunicationsService { public async Task> SendInviteAsync(InviteRequest request, Guid userId, CancellationToken cancellationToken = default) => @@ -39,12 +39,12 @@ public sealed class CommunicationsService(IDbContextFactory 0, + return Result.OkIf(await context.SaveChangesAsync(cancellationToken) > 0, CreateError.Create("Failed to create entry, contact support")); })); @@ -164,4 +164,59 @@ public sealed class CommunicationsService(IDbContextFactory> GetApplicantDataAsync(Guid applicantUserId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); + + var invites = await context.Invites.AsNoTracking() + .Where(i => i.Recipient == applicantUserId) + .OrderByDescending(o => o.Id) + .ToListAsync(cancellationToken); + + var applicantData = new List(); + + foreach (var invite in invites) + { + var outputInvite = invite.Map(); + + var contract = (await context.Contracts.AsNoTracking() + .FirstOrDefaultAsync(c => c.Id == invite.ContractId, cancellationToken))?.Map(); + + var fundingOrganisation = (await context.Organisations.AsNoTracking() + .FirstOrDefaultAsync(o => o.Id == invite.OrganisationId, cancellationToken))?.Map(); + + var invitedOrganisation = (await context.Organisations.AsNoTracking() + .FirstOrDefaultAsync(o => o.Id == invite.InvitedOrganisationId, cancellationToken))?.Map(); + + var awards = (await context.Awards.AsNoTracking() + .Where(a => a.Id == invite.AwardId) + .ToListAsync(cancellationToken))?.Select(a => a.Map()).ToArray(); + + var projectIds = (await context.Awards.AsNoTracking() + .Where(a => a.Id == invite.AwardId && a.ProjectId.HasValue) + .Select(a => a.ProjectId!.Value) + .Distinct() + .ToListAsync(cancellationToken)) ?? []; + + var projects = (await context.Projects.AsNoTracking() + .Where(p => projectIds.Contains(p.Id)) + .ToListAsync(cancellationToken))?.Select(p => p.Map()).ToArray() ?? []; + + var data = new ApplicantData + { + Invite = outputInvite, + Contract = contract, + Awards = awards!, + FundingOrganisation = fundingOrganisation, + InvitedOrganisation = invitedOrganisation, + Projects = projects + }; + + applicantData.Add(data); + } + + return Result.Ok(applicantData.ToArray()); + })); } diff --git a/PostFundManagement.Domain/Models/ApplicantData.cs b/PostFundManagement.Domain/Models/ApplicantData.cs new file mode 100644 index 0000000..3033888 --- /dev/null +++ b/PostFundManagement.Domain/Models/ApplicantData.cs @@ -0,0 +1,16 @@ +namespace PostFundManagement.Domain.Models; + +public sealed class ApplicantData +{ + public Invite? Invite { get; set; } + + public Contract? Contract { get; set; } + + public Organisation? FundingOrganisation { get; set; } + + public Organisation? InvitedOrganisation { get; set; } + + public Award[] Awards { get; set; } = []; + + public Project[] Projects { get; set; } = []; +} From 8eca793f5f6c61acf0c553e8b63e59d892f951bd Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 10 Oct 2026 15:31:36 +0200 Subject: [PATCH 05/10] Added skoruba user service integration test --- .../Endpoints/Users/AddUserRoleEndpoint.cs | 2 +- .../Endpoints/Users/DeleteUserRoleEndpoint.cs | 2 +- .../Abstractions/Services/IUserService.cs | 4 +- .../Extensions/Security.cs | 7 +- .../Services/Users/UserCacheService.cs | 4 +- .../Services/Users/UserService.cs | 10 +- .../Abstractions/ISkorubaUserService.cs | 7 +- .../Security/SkorubaUserService.cs | 57 +++++---- .../PostFundManagement.Tests.csproj | 39 +++++++ .../SkorubaUserServiceIntegrationTests.cs | 109 ++++++++++++++++++ PostFundManagement.Tests/appsettings.json | 45 ++++++++ PostFundManagement.slnx | 3 + 12 files changed, 248 insertions(+), 41 deletions(-) create mode 100644 PostFundManagement.Tests/PostFundManagement.Tests.csproj create mode 100644 PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs create mode 100644 PostFundManagement.Tests/appsettings.json diff --git a/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs index 31109ec..359bb42 100644 --- a/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/AddUserRoleEndpoint.cs @@ -11,7 +11,7 @@ public sealed class AddUserRoleEndpoint : IEndpoint { public void Map(IEndpointRouteBuilder builder) { - builder.MapPatch("api/users/{userId:Guid}/roles/{roleId}", async (Guid userId, string roleId, HttpContext context, + builder.MapPatch("api/users/{userId:Guid}/roles/{roleId:Guid}", async (Guid userId, Guid roleId, HttpContext context, IUserService userService, CancellationToken cancellationToken = default) => await userService.AddUserRoleAsync(userId, roleId, context.GetUserId(), cancellationToken) switch { diff --git a/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs index 4977002..5938916 100644 --- a/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs +++ b/PostFundManagement.Api/Endpoints/Users/DeleteUserRoleEndpoint.cs @@ -11,7 +11,7 @@ public sealed class DeleteUserRoleEndpoint : IEndpoint { public void Map(IEndpointRouteBuilder builder) { - builder.MapDelete("api/users/{userId:Guid}/roles/{roleId}", async (Guid userId, string roleId, HttpContext context, + builder.MapDelete("api/users/{userId:Guid}/roles/{roleId:Guid}", async (Guid userId, Guid roleId, HttpContext context, IUserService service, CancellationToken cancellationToken = default) => await service.DeleteUserRoleAsync(userId, roleId, context.GetUserId(), cancellationToken) switch { diff --git a/PostFundManagement.Application/Abstractions/Services/IUserService.cs b/PostFundManagement.Application/Abstractions/Services/IUserService.cs index a6e7974..537c8b4 100644 --- a/PostFundManagement.Application/Abstractions/Services/IUserService.cs +++ b/PostFundManagement.Application/Abstractions/Services/IUserService.cs @@ -32,7 +32,7 @@ public interface IUserService [Log] [Audit] - Task AddUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default); + Task AddUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default); [Log] [Audit] @@ -57,5 +57,5 @@ public interface IUserService [Log] [Audit] - Task DeleteUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default); + Task DeleteUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Application/Extensions/Security.cs b/PostFundManagement.Application/Extensions/Security.cs index 029c3dc..e107b62 100644 --- a/PostFundManagement.Application/Extensions/Security.cs +++ b/PostFundManagement.Application/Extensions/Security.cs @@ -24,23 +24,20 @@ public static class Security if (!authOptions.Authority.EndsWith('/')) authOptions.Authority += "/"; - services.AddClientCredentialsTokenManagement() + services.AddClientCredentialsTokenManagement() .AddClient(SkorubaCredentialClient, client => { client.TokenEndpoint = new Uri($"{authOptions.Authority}connect/token"); client.ClientId = ClientId.Parse(authOptions.ClientId!); client.ClientSecret = ClientSecret.Parse(authOptions.ClientSecret!); client.Scope = Duende.AccessTokenManagement.Scope.ParseOrDefault(authOptions.Scope); - }); + }); services.AddHttpClient(SkorubaHttpClient, client => { client.BaseAddress = new Uri(configuration.GetConnectionString("SkorubaApi")!); }).AddClientCredentialsTokenHandler(ClientCredentialsClientName.Parse(SkorubaCredentialClient)); - services.AddKeyedScoped(SkorubaHttpClient, (provider, key) => - provider.GetRequiredService()); - services.AddScoped(); services.AddScoped(); services.AddSingleton(); diff --git a/PostFundManagement.Application/Services/Users/UserCacheService.cs b/PostFundManagement.Application/Services/Users/UserCacheService.cs index f4e5022..94605b7 100644 --- a/PostFundManagement.Application/Services/Users/UserCacheService.cs +++ b/PostFundManagement.Application/Services/Users/UserCacheService.cs @@ -14,7 +14,7 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach public async Task AddUserClaimAsync(AddUserClaimRequest request, Guid userId, CancellationToken cancellationToken = default) => await service.AddUserClaimAsync(request, userId, cancellationToken); - public async Task AddUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + public async Task AddUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => await service.AddUserRoleAsync(targetUserId, roleId, userId, cancellationToken); public async Task CreateUserAsync(string tenantIdHash, string idNumberHash, CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => @@ -23,7 +23,7 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach public async Task DeleteUserClaimAsync(string claimIdHash, Guid targetUserId, Guid userId, CancellationToken cancellationToken = default) => await service.DeleteUserClaimAsync(claimIdHash, targetUserId, userId, cancellationToken); - public async Task DeleteUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + public async Task DeleteUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => await service.DeleteUserRoleAsync(targetUserId, roleId, userId, cancellationToken); public async Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default) => diff --git a/PostFundManagement.Application/Services/Users/UserService.cs b/PostFundManagement.Application/Services/Users/UserService.cs index 76527f9..6eb981f 100644 --- a/PostFundManagement.Application/Services/Users/UserService.cs +++ b/PostFundManagement.Application/Services/Users/UserService.cs @@ -164,7 +164,7 @@ public sealed class UserService(IDbContextFactory contextF if (defaultRole == null) return Result.Fail(NotFoundError.Create("Role 'Contributor' not found.")); - var roleAssignmentResult = await skorubaService.AddRoleAsync(newUserId, defaultRole.Id, cancellationToken); + var roleAssignmentResult = await skorubaService.AddRoleAsync(newUserId, Guid.Parse(defaultRole.Id), cancellationToken); if (roleAssignmentResult.IsFailed) return Result.Fail(UpdateError.Create("Failed to assign role to user.")); @@ -255,7 +255,7 @@ public sealed class UserService(IDbContextFactory contextF await Result.Try((Func>>)(async () => await skorubaService.GetAvailableRolesAsync(cancellationToken: cancellationToken))); - public async Task DeleteUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + public async Task DeleteUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { await using var context = await contextFactory.CreateDbContextAsync(cancellationToken); @@ -278,7 +278,7 @@ public sealed class UserService(IDbContextFactory contextF .CausedBy(addClaimResult.Errors)); })); - public async Task AddUserRoleAsync(Guid targetUserId, string roleId, Guid userId, CancellationToken cancellationToken = default) => + public async Task AddUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { var userRolesResult = await skorubaService.GetUserRolesAsync(targetUserId, cancellationToken: cancellationToken); @@ -289,7 +289,7 @@ public sealed class UserService(IDbContextFactory contextF foreach (var role in userRolesResult.Value) { - var deleteRoleResult = await skorubaService.RemoveRoleAsync(targetUserId, role.Id, cancellationToken); + var deleteRoleResult = await skorubaService.RemoveRoleAsync(targetUserId, Guid.Parse(role.Id), cancellationToken); if (deleteRoleResult.IsFailed) return Result.Fail(UpdateError.Create("Failed to remove existing user role.") @@ -308,7 +308,7 @@ public sealed class UserService(IDbContextFactory contextF return Result.Fail(NotFoundError.Create("Failed to retrieve system roles.") .CausedBy(systemRoles.Errors)); - var targetRole = systemRoles.Value.FirstOrDefault(r => r.Id == roleId); + var targetRole = systemRoles.Value.FirstOrDefault(r => r.Id == roleId.ToString()); if (targetRole == null) return Result.Fail(NotFoundError.Create("Role not found.")); diff --git a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs index 3294d03..83a354e 100644 --- a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs +++ b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs @@ -30,11 +30,11 @@ public interface ISkorubaUserService [Log] [Audit] - Task AddRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default); + Task AddRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default); [Log] [Audit] - Task RemoveRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default); + Task RemoveRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default); [Log] Task> GetAvailableRolesAsync(string? searchText = null, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); @@ -45,6 +45,9 @@ public interface ISkorubaUserService [Log] Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + [Log] + Task> GetRoleClaimsAsync(Guid roleId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + [Log] Task InvalidateUserSessionAsync(Guid userId, CancellationToken cancellationToken = default); } diff --git a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs index f070cfe..333a886 100644 --- a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs +++ b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs @@ -4,12 +4,12 @@ using PostFundManagement.Domain.Models.Security; namespace PostFundManagement.Infrastructure.Security; -public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClientFactory httpClientFactory) : ISkorubaUserService +public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkorubaUserService { public async Task> CreateUserAsync(CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var response = await httpClient.PostAsJsonAsync("api/users", request, cancellationToken); if (!response.IsSuccessStatusCode) @@ -24,7 +24,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task> GetUserAsync(Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var result = await httpClient.GetFromJsonAsync($"api/users/{userId}", cancellationToken); return Result.FailIf(result is null, NotFoundError.Create($"User {userId} not found.")) @@ -34,7 +34,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task UpdateUserAsync(UpdateUserRequest request, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var response = await httpClient.PutAsJsonAsync("api/users", request, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, UpdateError.Create("Failed to update user.")); @@ -43,7 +43,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task SetUserLockoutAsync(Guid userId, bool disabled, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var user = await httpClient.GetFromJsonAsync($"api/users/{userId}", cancellationToken); if (user is null) @@ -63,7 +63,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task AddClaimAsync(Guid userId, string claimType, string claimValue, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var payload = new { UserId = userId, ClaimType = claimType, ClaimValue = claimValue }; var response = await httpClient.PostAsJsonAsync($"api/users/{userId}/claims", payload, cancellationToken); @@ -74,7 +74,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task RemoveClaimAsync(Guid userId, int claimId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var response = await httpClient.DeleteAsync($"api/users/{userId}/claims/{claimId}", cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user claim.")); @@ -83,7 +83,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var result = await httpClient.GetFromJsonAsync($"api/users/{userId}/claims?page={page}&pageSize={pageSize}", cancellationToken); @@ -91,10 +91,10 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie .ToResult(result?.Claims.ToArray() ?? []); })); - public async Task AddRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default) => + public async Task AddRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var payload = new { UserId = userId, RoleId = roleId }; var response = await httpClient.PostAsJsonAsync($"api/users/{userId}/roles", payload, cancellationToken); @@ -102,10 +102,10 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to add user role.")); })); - public async Task RemoveRoleAsync(Guid userId, string roleId, CancellationToken cancellationToken = default) => + public async Task RemoveRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var response = await httpClient.DeleteAsync($"api/users/{userId}/roles/{roleId}", cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user role.")); @@ -114,7 +114,7 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task> GetUserRolesAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var result = await httpClient.GetFromJsonAsync($"api/users/{userId}/roles?page={page}&pageSize={pageSize}", cancellationToken); @@ -122,10 +122,21 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie .ToResult(result?.Roles?.ToArray() ?? []); })); + public async Task> GetRoleClaimsAsync(Guid roleId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + + var result = await httpClient.GetFromJsonAsync($"api/roles/{roleId}/claims?page={page}&pageSize={pageSize}", cancellationToken); + + return Result.FailIf(result is null, NotFoundError.Create($"Claims for role {roleId} could not be retrieved.")) + .ToResult(result?.Claims.ToArray() ?? []); + })); + public async Task InvalidateUserSessionAsync(Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>)(async () => { - var httpClient = httpClientFactory.CreateClient(); + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var user = await httpClient.GetFromJsonAsync($"api/users/{userId}", cancellationToken); if (user is null) @@ -138,17 +149,17 @@ public class SkorubaUserService([FromKeyedServices(SkorubaHttpClient)] IHttpClie public async Task> GetAvailableRolesAsync(string? searchText = null, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => - { - var httpClient = httpClientFactory.CreateClient(); + { + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var query = $"api/roles?page={page}&pageSize={pageSize}"; + var query = $"api/roles?page={page}&pageSize={pageSize}"; - if (!string.IsNullOrWhiteSpace(searchText)) - query += $"&searchText={Uri.EscapeDataString(searchText)}"; + if (!string.IsNullOrWhiteSpace(searchText)) + query += $"&searchText={Uri.EscapeDataString(searchText)}"; - var result = await httpClient.GetFromJsonAsync(query, cancellationToken); + var result = await httpClient.GetFromJsonAsync(query, cancellationToken); - return Result.FailIf(result is null, NotFoundError.Create("Available roles could not be retrieved.")) - .ToResult(result?.Roles?.ToArray() ?? []); - })); + return Result.FailIf(result is null, NotFoundError.Create("Available roles could not be retrieved.")) + .ToResult(result?.Roles?.ToArray() ?? []); + })); } \ No newline at end of file diff --git a/PostFundManagement.Tests/PostFundManagement.Tests.csproj b/PostFundManagement.Tests/PostFundManagement.Tests.csproj new file mode 100644 index 0000000..497b59a --- /dev/null +++ b/PostFundManagement.Tests/PostFundManagement.Tests.csproj @@ -0,0 +1,39 @@ + + + + net10.0 + enable + enable + false + 079fcde1-9b10-4402-9624-5f0827b4dbfd + + + + + PreserveNewest + true + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs new file mode 100644 index 0000000..ad0316c --- /dev/null +++ b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs @@ -0,0 +1,109 @@ +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Infrastructure.Database.Services; +using System.Diagnostics; +using static PostFundManagement.Domain.Extensions.Constants; + +namespace PostFundManagement.Tests; + +/// +/// Integration tests for SkorubaUserService.GetUserRolesAsync method. +/// +/// These tests hit the actual Skoruba API environment. +/// Requires the following configuration: +/// - MachineIdentitySettings with valid ClientId and ClientSecret from user secrets +/// - SkorubaApi connection string pointing to the API endpoint +/// - Network access to the Skoruba API +/// +/// To run these tests: +/// dotnet test --filter "FullyQualifiedName~SkorubaUserServiceGetUserRolesIntegrationTests" +/// +public class SkorubaUserServiceGetUserRolesIntegrationTests +{ + private readonly ISkorubaUserService _skorubaService; + private readonly IHttpClientFactory _httpClientFactory; + + public SkorubaUserServiceGetUserRolesIntegrationTests() + { + var services = new ServiceCollection(); + + // Load configuration from environment and secrets + var configuration = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", optional: true) + .AddUserSecrets(Assembly.GetExecutingAssembly(), optional: true) + .AddEnvironmentVariables() + .Build(); + + services.AddSingleton(configuration); + services.AddHttpClient(); + + // Register the Skoruba HTTP client with the actual DI configuration + services.AddSkorubaApiService(configuration) + .AddRegisterServicesWithCaching(configuration) + .AddEndpointAndServiceCaching(configuration) + .AddSharedServices() + .AddHashServices(configuration) + .AddApplicationDbContext(configuration) + .AddHttpContextAccessor() + .AddTransient(); + + var serviceProvider = services.BuildServiceProvider(); + _skorubaService = serviceProvider.GetRequiredService(); + _httpClientFactory = serviceProvider.GetRequiredService(); + } + + /// + /// Integration test: Verify HttpClient is properly configured with SkorubaHttpClient name. + /// + //[Fact(Skip = "Skipping integration test")] + [Fact] + public void HttpClientFactory_HasSkorubaHttpClientConfigured() + { + // Act + var httpClient = _httpClientFactory.CreateClient(SkorubaHttpClient); + + // Assert + Assert.NotNull(httpClient); + Assert.NotNull(httpClient.BaseAddress); + } + + /// + /// Integration test: Verify that the service properly formats API requests. + /// Uses a fake/invalid user ID to test the HTTP request flow. + /// + //[Fact(Skip = "Skipping integration test")] + [Fact] + public async Task GetUserRolesAsync_SendsProperlyFormattedRequest() + { + // Arrange + var userId = Guid.NewGuid(); + var page = 2; + var pageSize = 25; + + // Act - This will likely fail with 401 or 404 + var result = await _skorubaService.GetUserRolesAsync(userId, page, pageSize); + + // Assert - Request was processed (even if it failed) + Assert.False(result.IsSuccess); + Assert.NotNull(result.Errors); + } + + /// + /// Integration test: Verify cancellation token is respected. + /// + //[Fact(Skip = "Skipping integration test")] + [Fact] + public async Task GetUserRolesAsync_RespectsCancellationToken() + { + // Arrange + var userId = Guid.NewGuid(); + var cts = new CancellationTokenSource(); + cts.Cancel(); + + // Act & Assert + await Assert.ThrowsAsync(async () => + { + await _skorubaService.GetUserRolesAsync(userId, cancellationToken: cts.Token); + }); + } +} diff --git a/PostFundManagement.Tests/appsettings.json b/PostFundManagement.Tests/appsettings.json new file mode 100644 index 0000000..58a2660 --- /dev/null +++ b/PostFundManagement.Tests/appsettings.json @@ -0,0 +1,45 @@ +{ + "EnableServiceCaching": true, + "CorsOrigins": [ + "https://console.ifri.khongisa.co.za", + "https://localhost:7208" + ], + "GeneralS3Settings": { + "ServiceUrl": "https://s3.garage.khongisa.co.za", + "Region": "garage", + "BucketName": "pfm", + "CdnBaseUrl": "https://pfm.cdn.khongisa.co.za" + }, + "Monitoring": { + "Address": "http://aspire-dashboard-service.aspire.svc.cluster.local:18889", + "ServiceName": "Pfm.DEV" + }, + "SecuritySettings": { + "Authority": "https://sts.security.khongisa.co.za", + "Audience": "pfm-api-dev" + }, + "MachineIdentitySettings": { + "Authority": "https://sts.security.khongisa.co.za", + "Scope": "skoruba_identity_admin_api" + }, + "Logging": { + "LogLevel": { + "Default": "Warning", + "Quartz": "Error", + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore.Database": "Error", + "Microsoft.EntityFrameworkCore.Update": "Error" + } + }, + "EmailProcessorCron": "0 */5 * * * ?", + "Email": { + "SmtpServer": "smtp.example.com", + "SmtpPort": 587, + "SenderEmail": "noreply@example.com", + "SenderName": "Example" + }, + "HasherSettings": { + "MinHashLength": 11 + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/PostFundManagement.slnx b/PostFundManagement.slnx index 9982c4f..c829b6c 100644 --- a/PostFundManagement.slnx +++ b/PostFundManagement.slnx @@ -7,6 +7,9 @@ + + + From 0352d154a4f18b2ec9602f4e883d30cd0577a654 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 10 Oct 2026 15:35:32 +0200 Subject: [PATCH 06/10] Added debug only fact --- PostFundManagement.Tests/DebugOnlyFactAttribute.cs | 12 ++++++++++++ .../PostFundManagement.Tests.csproj | 1 + .../SkorubaUserServiceIntegrationTests.cs | 11 ++++------- 3 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 PostFundManagement.Tests/DebugOnlyFactAttribute.cs diff --git a/PostFundManagement.Tests/DebugOnlyFactAttribute.cs b/PostFundManagement.Tests/DebugOnlyFactAttribute.cs new file mode 100644 index 0000000..b32aeb8 --- /dev/null +++ b/PostFundManagement.Tests/DebugOnlyFactAttribute.cs @@ -0,0 +1,12 @@ +namespace PostFundManagement.Tests; + +public class DebugOnlyFactAttribute : FactAttribute +{ + public DebugOnlyFactAttribute() + { + if (!Debugger.IsAttached) + { + Skip = "This test only runs when a debugger is attached."; + } + } +} diff --git a/PostFundManagement.Tests/PostFundManagement.Tests.csproj b/PostFundManagement.Tests/PostFundManagement.Tests.csproj index 497b59a..7e7e4ae 100644 --- a/PostFundManagement.Tests/PostFundManagement.Tests.csproj +++ b/PostFundManagement.Tests/PostFundManagement.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs index ad0316c..517c6be 100644 --- a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs +++ b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs @@ -54,9 +54,8 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests /// /// Integration test: Verify HttpClient is properly configured with SkorubaHttpClient name. - /// - //[Fact(Skip = "Skipping integration test")] - [Fact] + /// + [DebugOnlyFact] public void HttpClientFactory_HasSkorubaHttpClientConfigured() { // Act @@ -71,8 +70,7 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests /// Integration test: Verify that the service properly formats API requests. /// Uses a fake/invalid user ID to test the HTTP request flow. /// - //[Fact(Skip = "Skipping integration test")] - [Fact] + [DebugOnlyFact] public async Task GetUserRolesAsync_SendsProperlyFormattedRequest() { // Arrange @@ -91,8 +89,7 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests /// /// Integration test: Verify cancellation token is respected. /// - //[Fact(Skip = "Skipping integration test")] - [Fact] + [DebugOnlyFact] public async Task GetUserRolesAsync_RespectsCancellationToken() { // Arrange From d3566c5e43f669c9b45a7a3e3c580b6616a87957 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 10 Oct 2026 15:44:27 +0200 Subject: [PATCH 07/10] Light refactor --- .../SkorubaUserServiceIntegrationTests.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs index 517c6be..f216b8e 100644 --- a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs +++ b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs @@ -1,7 +1,6 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; using PostFundManagement.Infrastructure.Database.Services; -using System.Diagnostics; using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Tests; @@ -74,16 +73,16 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests public async Task GetUserRolesAsync_SendsProperlyFormattedRequest() { // Arrange - var userId = Guid.NewGuid(); + var userId = Guid.Parse("6059f1e4-6a41-4447-a546-86ece5102004"); var page = 2; var pageSize = 25; - // Act - This will likely fail with 401 or 404 + // Act var result = await _skorubaService.GetUserRolesAsync(userId, page, pageSize); - // Assert - Request was processed (even if it failed) - Assert.False(result.IsSuccess); - Assert.NotNull(result.Errors); + // Assert + Assert.True(result.IsSuccess, result.Errors[0].Message); + Assert.Empty(result.Errors); } /// From 381d5b7e940495e5c7420809e8bfe62c9064fa29 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sat, 10 Oct 2026 18:14:31 +0200 Subject: [PATCH 08/10] Stable user lockout, role and claim calls --- .../Endpoints/Users/GetRoleClaimsEndpoint.cs | 34 ++++++ .../Abstractions/Services/IUserService.cs | 3 + .../Extensions/Security.cs | 18 +-- .../Handlers/ClientCredentialsTokenHandler.cs | 115 ++++++++++++++++++ .../Services/Users/UserCacheService.cs | 25 ++++ .../Services/Users/UserService.cs | 4 + .../Abstractions/ISkorubaUserService.cs | 2 +- .../Security/MachineIdentitySettings.cs | 2 +- .../Models/Security/Contracts.cs | 33 +++++ .../Security/SkorubaUserService.cs | 31 ++++- .../SkorubaUserServiceIntegrationTests.cs | 4 +- 11 files changed, 249 insertions(+), 22 deletions(-) create mode 100644 PostFundManagement.Api/Endpoints/Users/GetRoleClaimsEndpoint.cs create mode 100644 PostFundManagement.Application/Handlers/ClientCredentialsTokenHandler.cs diff --git a/PostFundManagement.Api/Endpoints/Users/GetRoleClaimsEndpoint.cs b/PostFundManagement.Api/Endpoints/Users/GetRoleClaimsEndpoint.cs new file mode 100644 index 0000000..15d3f6b --- /dev/null +++ b/PostFundManagement.Api/Endpoints/Users/GetRoleClaimsEndpoint.cs @@ -0,0 +1,34 @@ +using PostFundManagement.Application.Abstractions.Services; +using PostFundManagement.Application.Extensions; +using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Errors; +using PostFundManagement.Domain.Extensions; + +namespace PostFundManagement.Api.Endpoints.Users; + +[ApiVersionTarget(1)] +public sealed class GetRoleClaimsEndpoint : IEndpoint +{ + public void Map(IEndpointRouteBuilder builder) + { + builder.MapGet("api/users/system/roles/{roleId:Guid}/claims", async (Guid roleId, HttpContext context, + IUserService service, CancellationToken cancellationToken = default) => + await service.GetRoleClaimsAsync(roleId, context.GetUserId(), cancellationToken) switch + { + { IsSuccess: true, Value: var claims } => Results.Ok(claims), + var r when r.HasError() => Results.NotFound(r.Errors.ToProblems()), + var r when r.HasError() => Results.BadRequest(r.Errors.ToProblems()), + var r => Results.InternalServerError(r.Errors.ToProblems()) + }) + .WithDescription("Get system role claims") + .RequireAuthorization(Constants.MainScope) + .WithName(typeof(GetRoleClaimsEndpoint).ToEndpointName()) + .MapToApiVersion(new ApiVersion(1)) + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status401Unauthorized) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status400BadRequest) + .Produces(StatusCodes.Status500InternalServerError) + .WithTags(EndpointTags.Users); + } +} diff --git a/PostFundManagement.Application/Abstractions/Services/IUserService.cs b/PostFundManagement.Application/Abstractions/Services/IUserService.cs index 537c8b4..1666db4 100644 --- a/PostFundManagement.Application/Abstractions/Services/IUserService.cs +++ b/PostFundManagement.Application/Abstractions/Services/IUserService.cs @@ -52,6 +52,9 @@ public interface IUserService [Log] Task> GetUserClaimsAsync(Guid targetUserId, Guid userId, CancellationToken cancellationToken = default); + [Log] + Task> GetRoleClaimsAsync(Guid roleId, Guid userId, CancellationToken cancellationToken = default); + [Log] Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default); diff --git a/PostFundManagement.Application/Extensions/Security.cs b/PostFundManagement.Application/Extensions/Security.cs index e107b62..7bb6e8f 100644 --- a/PostFundManagement.Application/Extensions/Security.cs +++ b/PostFundManagement.Application/Extensions/Security.cs @@ -1,3 +1,4 @@ +using PostFundManagement.Application.Handlers; using PostFundManagement.Application.Interceptors; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Domain.Abstractions; @@ -24,19 +25,10 @@ public static class Security if (!authOptions.Authority.EndsWith('/')) authOptions.Authority += "/"; - services.AddClientCredentialsTokenManagement() - .AddClient(SkorubaCredentialClient, client => - { - client.TokenEndpoint = new Uri($"{authOptions.Authority}connect/token"); - client.ClientId = ClientId.Parse(authOptions.ClientId!); - client.ClientSecret = ClientSecret.Parse(authOptions.ClientSecret!); - client.Scope = Duende.AccessTokenManagement.Scope.ParseOrDefault(authOptions.Scope); - }); - - services.AddHttpClient(SkorubaHttpClient, client => - { - client.BaseAddress = new Uri(configuration.GetConnectionString("SkorubaApi")!); - }).AddClientCredentialsTokenHandler(ClientCredentialsClientName.Parse(SkorubaCredentialClient)); + services.AddTransient(); + + services.AddHttpClient(SkorubaHttpClient, client => client.BaseAddress = new Uri(configuration.GetConnectionString("SkorubaApi")!)) + .AddHttpMessageHandler(); services.AddScoped(); services.AddScoped(); diff --git a/PostFundManagement.Application/Handlers/ClientCredentialsTokenHandler.cs b/PostFundManagement.Application/Handlers/ClientCredentialsTokenHandler.cs new file mode 100644 index 0000000..b2ad9c0 --- /dev/null +++ b/PostFundManagement.Application/Handlers/ClientCredentialsTokenHandler.cs @@ -0,0 +1,115 @@ +using IdentityModel.Client; +using PostFundManagement.Domain.Configuration.Security; + +namespace PostFundManagement.Application.Handlers; + +public class ClientCredentialsTokenHandler(ILogger logger, + IOptions options) : DelegatingHandler +{ + private readonly MachineIdentitySettings _settings = options.Value; + private string? _cachedToken; + private DateTime _tokenExpiry = DateTime.MinValue; + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + try + { + var token = await GetAccessTokenAsync(cancellationToken); + + if (string.IsNullOrWhiteSpace(token)) + { + logger.LogError("Failed to acquire access token for Skoruba API"); + + throw new InvalidOperationException("Unable to acquire access token"); + } + + request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token); + + logger.LogDebug("ClientCredentialsTokenHandler: Added bearer token to request"); + } + catch (Exception ex) + { + logger.LogError(ex, "Error acquiring client credentials token"); + + throw; + } + + try + { + var response = await base.SendAsync(request, cancellationToken); + + if (!response.IsSuccessStatusCode) + { + logger.LogWarning("HTTP request failed with status {StatusCode} for {Method} {RequestUri}", + response.StatusCode, request.Method, request.RequestUri); + } + + return response; + } + catch (Exception ex) + { + logger.LogError(ex, "Error sending HTTP request with client credentials token"); + + throw; + } + } + + private async Task GetAccessTokenAsync(CancellationToken cancellationToken) + { + if (!string.IsNullOrWhiteSpace(_cachedToken) && DateTime.UtcNow < _tokenExpiry) + { + logger.LogDebug("Using cached access token"); + + return _cachedToken; + } + + logger.LogDebug("Acquiring new access token from {Authority}", _settings.Authority); + + using var tokenClient = new HttpClient(); + + try + { + if (!_settings.Authority!.EndsWith('/')) _settings.Authority += "/"; + + var scope = _settings.Scope; + + var tokenRequest = new ClientCredentialsTokenRequest + { + Address = $"{_settings.Authority}connect/token", + ClientId = _settings.ClientId!, + ClientSecret = _settings.ClientSecret, + GrantType = "client_credentials", + Scope = scope, + }; + + logger.LogDebug("Sending token request to {TokenEndpoint} for client {ClientId} with scope {Scope}", + tokenRequest.Address, tokenRequest.ClientId, tokenRequest.Scope); + + var response = await tokenClient.RequestClientCredentialsTokenAsync(tokenRequest, cancellationToken); + + if (response.IsError) + { + logger.LogError("Token request error: {Error} - {ErrorDescription}. Full response: {Raw}", + response.Error, response.ErrorDescription, response.Raw); + + return null; + } + + _cachedToken = response.AccessToken; + + var expiresIn = response.ExpiresIn > 0 ? response.ExpiresIn : 3600; + + _tokenExpiry = DateTime.UtcNow.AddSeconds(expiresIn * 0.9); + + logger.LogDebug("Successfully acquired access token, expires at {Expiry}", _tokenExpiry); + + return _cachedToken; + } + catch (Exception ex) + { + logger.LogError(ex, "Exception occurred while acquiring client credentials token"); + + throw; + } + } +} diff --git a/PostFundManagement.Application/Services/Users/UserCacheService.cs b/PostFundManagement.Application/Services/Users/UserCacheService.cs index 94605b7..cee62f5 100644 --- a/PostFundManagement.Application/Services/Users/UserCacheService.cs +++ b/PostFundManagement.Application/Services/Users/UserCacheService.cs @@ -26,6 +26,31 @@ public sealed class UserCacheService(UserService service, IDistributedCache cach public async Task DeleteUserRoleAsync(Guid targetUserId, Guid roleId, Guid userId, CancellationToken cancellationToken = default) => await service.DeleteUserRoleAsync(targetUserId, roleId, userId, cancellationToken); + public async Task> GetRoleClaimsAsync(Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + { + if (!await featureManager.IsEnabledAsync(ServiceCachingFeature)) + return await service.GetRoleClaimsAsync(roleId, userId, cancellationToken); + + var cacheKey = HashService.ToMd5Hash($"getsystemroles-{userId}").Value; + + var cached = await cache.GetStringAsync(cacheKey, cancellationToken); + + if (string.IsNullOrWhiteSpace(cached)) + { + var claimResult = await service.GetRoleClaimsAsync(roleId, userId, cancellationToken); + + if (claimResult.IsFailed) return claimResult; + + await cache.SetStringAsync(cacheKey, claimResult.Value.ToJson(), + cacheOptions, cancellationToken); + + return claimResult; + } + + return Result.Ok(cached.FromJson()); + })); + public async Task> GetSystemRolesAsync(Guid userId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { diff --git a/PostFundManagement.Application/Services/Users/UserService.cs b/PostFundManagement.Application/Services/Users/UserService.cs index 6eb981f..4639a68 100644 --- a/PostFundManagement.Application/Services/Users/UserService.cs +++ b/PostFundManagement.Application/Services/Users/UserService.cs @@ -321,4 +321,8 @@ public sealed class UserService(IDbContextFactory contextF return Result.OkIf(roleAddResult.IsSuccess && changedTotal > 0, ValidationError.Create("Failed to add user role.") .CausedBy(roleAddResult.Errors)); })); + + public async Task> GetRoleClaimsAsync(Guid roleId, Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>>)(async () => + await skorubaService.GetRoleClaimsAsync(roleId, cancellationToken))); } diff --git a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs index 83a354e..1317e9e 100644 --- a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs +++ b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs @@ -46,7 +46,7 @@ public interface ISkorubaUserService Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); [Log] - Task> GetRoleClaimsAsync(Guid roleId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default); + Task> GetRoleClaimsAsync(Guid roleId, CancellationToken cancellationToken = default); [Log] Task InvalidateUserSessionAsync(Guid userId, CancellationToken cancellationToken = default); diff --git a/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs b/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs index a917b66..f705aa0 100644 --- a/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs +++ b/PostFundManagement.Domain/Configuration/Security/MachineIdentitySettings.cs @@ -9,4 +9,4 @@ public sealed class MachineIdentitySettings public string? ClientId { get; set; } public string? ClientSecret { get; set; } -} \ No newline at end of file +} diff --git a/PostFundManagement.Domain/Models/Security/Contracts.cs b/PostFundManagement.Domain/Models/Security/Contracts.cs index e4d1260..03defb6 100644 --- a/PostFundManagement.Domain/Models/Security/Contracts.cs +++ b/PostFundManagement.Domain/Models/Security/Contracts.cs @@ -2,6 +2,39 @@ namespace PostFundManagement.Domain.Models.Security; +public sealed class UserLockOutRequest +{ + [JsonPropertyName("id")] + public string? UserId { get; set; } + + [JsonPropertyName("userName")] + public string? UserName { get; set; } + + [JsonPropertyName("email")] + public string? Email { get; set; } + + [JsonPropertyName("emailConfirmed")] + public bool EmailConfirmed { get; set; } + + [JsonPropertyName("phoneNumber")] + public string? PhoneNumber { get; set; } + + [JsonPropertyName("phoneNumberConfirmed")] + public bool PhoneNumberConfirmed { get; set; } + + [JsonPropertyName("LockoutEnabled")] + public bool LockoutEnabled { get; set; } + + [JsonPropertyName("twoFactorEnabled")] + public bool TwoFactorEnabled { get; set; } + + [JsonPropertyName("accessFailedCount")] + public int AccessFailedCount { get; set; } + + [JsonPropertyName("lockoutEnd")] + public DateTimeOffset? LockoutEnd { get; set; } +} + public sealed record AddUserClaimRequest([Required] Guid UserId, [Required] int ClaimId, [Required][MaxLength(LabelLength)] string ClaimType, diff --git a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs index 333a886..9886324 100644 --- a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs +++ b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs @@ -49,9 +49,17 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba if (user is null) return Result.Fail(NotFoundError.Create($"User {userId} not found.")); - var updated = user with + var updated = new UserLockOutRequest { + UserId = userId.ToString(), + UserName = user.UserName, + Email = user.Email, + EmailConfirmed = user.EmailConfirmed, + PhoneNumber = user.PhoneNumber, + PhoneNumberConfirmed = user.PhoneNumberConfirmed, LockoutEnabled = true, + TwoFactorEnabled = user.TwoFactorEnabled, + AccessFailedCount = user.AccessFailedCount, LockoutEnd = disabled ? DateTimeOffset.UtcNow.AddYears(100) : null }; @@ -97,7 +105,7 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var payload = new { UserId = userId, RoleId = roleId }; - var response = await httpClient.PostAsJsonAsync($"api/users/{userId}/roles", payload, cancellationToken); + var response = await httpClient.PostAsJsonAsync($"api/users/roles", payload, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to add user role.")); })); @@ -106,7 +114,17 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba await Result.Try((Func>)(async () => { var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var response = await httpClient.DeleteAsync($"api/users/{userId}/roles/{roleId}", cancellationToken); + + var request = new HttpRequestMessage(HttpMethod.Delete, "api/Users/Roles") + { + Content = JsonContent.Create(new + { + userId = userId.ToString(), + roleId = roleId.ToString() + }) + }; + + var response = await httpClient.SendAsync(request, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user role.")); })); @@ -116,17 +134,20 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba { var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var result = await httpClient.GetFromJsonAsync($"api/users/{userId}/roles?page={page}&pageSize={pageSize}", cancellationToken); + var result = await httpClient.GetFromJsonAsync($"api/Users/{userId}/Roles?page={page}&pageSize={pageSize}", cancellationToken); return Result.FailIf(result is null, NotFoundError.Create($"Roles for user {userId} could not be retrieved.")) .ToResult(result?.Roles?.ToArray() ?? []); })); - public async Task> GetRoleClaimsAsync(Guid roleId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => + public async Task> GetRoleClaimsAsync(Guid roleId, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + var page = 1; + var pageSize = 100; + var result = await httpClient.GetFromJsonAsync($"api/roles/{roleId}/claims?page={page}&pageSize={pageSize}", cancellationToken); return Result.FailIf(result is null, NotFoundError.Create($"Claims for role {roleId} could not be retrieved.")) diff --git a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs index f216b8e..6df913d 100644 --- a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs +++ b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs @@ -74,14 +74,14 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests { // Arrange var userId = Guid.Parse("6059f1e4-6a41-4447-a546-86ece5102004"); - var page = 2; + var page = 1; var pageSize = 25; // Act var result = await _skorubaService.GetUserRolesAsync(userId, page, pageSize); // Assert - Assert.True(result.IsSuccess, result.Errors[0].Message); + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); Assert.Empty(result.Errors); } From 9a0371fb088e174ac0c84caf5efa0c212e3d59f4 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 11 Oct 2026 07:43:51 +0200 Subject: [PATCH 09/10] Added skorubauserservice tests --- .../Services/Users/UserService.cs | 2 +- .../Abstractions/ISkorubaUserService.cs | 6 +- .../Models/Security/Contracts.cs | 16 +- .../Security/SkorubaUserService.cs | 28 ++- .../SkorubaUserServiceIntegrationTests.cs | 168 +++++++++++++++--- PostFundManagement.slnx | 4 +- 6 files changed, 181 insertions(+), 43 deletions(-) diff --git a/PostFundManagement.Application/Services/Users/UserService.cs b/PostFundManagement.Application/Services/Users/UserService.cs index 4639a68..5c25bcf 100644 --- a/PostFundManagement.Application/Services/Users/UserService.cs +++ b/PostFundManagement.Application/Services/Users/UserService.cs @@ -147,7 +147,7 @@ public sealed class UserService(IDbContextFactory contextF if (await context.Users.AnyAsync(u => u.Email == email, cancellationToken)) return Result.Fail(ValidationError.Create("User with this email already exists.")); - var createUserResult = await skorubaService.CreateUserAsync(request, userId, cancellationToken); + var createUserResult = await skorubaService.CreateUserAsync(request, cancellationToken); if (createUserResult.IsFailed) return Result.Fail(CreateError.Create("Failed to create user.")); diff --git a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs index 1317e9e..f0f9faf 100644 --- a/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs +++ b/PostFundManagement.Domain/Abstractions/ISkorubaUserService.cs @@ -7,7 +7,11 @@ public interface ISkorubaUserService { [Log] [Audit] - Task> CreateUserAsync(CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default); + Task> CreateUserAsync(CreateUserRequest request, CancellationToken cancellationToken = default); + + [Log] + [Audit] + Task RemoveUserAsync(Guid userId, CancellationToken cancellationToken = default); [Log] Task> GetUserAsync(Guid userId, CancellationToken cancellationToken = default); diff --git a/PostFundManagement.Domain/Models/Security/Contracts.cs b/PostFundManagement.Domain/Models/Security/Contracts.cs index 03defb6..86ea49e 100644 --- a/PostFundManagement.Domain/Models/Security/Contracts.cs +++ b/PostFundManagement.Domain/Models/Security/Contracts.cs @@ -2,7 +2,7 @@ namespace PostFundManagement.Domain.Models.Security; -public sealed class UserLockOutRequest +public abstract class SkorubaUser { [JsonPropertyName("id")] public string? UserId { get; set; } @@ -35,15 +35,15 @@ public sealed class UserLockOutRequest public DateTimeOffset? LockoutEnd { get; set; } } -public sealed record AddUserClaimRequest([Required] Guid UserId, - [Required] int ClaimId, - [Required][MaxLength(LabelLength)] string ClaimType, +public sealed class UserLockOutRequest : SkorubaUser; +public sealed class CreateUserRequest : SkorubaUser; +public sealed class UpdateUserRequest : SkorubaUser; + +public sealed record AddUserClaimRequest([Required] Guid UserId, + [Required] int ClaimId, + [Required][MaxLength(LabelLength)] string ClaimType, [Required][MaxLength(LabelLength)] string ClaimValue); -public sealed record CreateUserRequest(string UserName, string Email, string Password, bool EmailConfirmed = true, string? PhoneNumber = null, bool PhoneNumberConfirmed = false); - -public sealed record UpdateUserRequest(string UserId, string UserName, string Email, bool EmailConfirmed, string? PhoneNumber, bool PhoneNumberConfirmed, bool LockoutEnabled, DateTimeOffset? LockoutEnd, int AccessFailedCount, bool TwoFactorEnabled); - public sealed record Claim(string ClaimType, string ClaimValue, int? ClaimId = null); public sealed record ClaimsResponse(int TotalCount, int PageSize, ICollection Claims); diff --git a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs index 9886324..366477f 100644 --- a/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs +++ b/PostFundManagement.Infrastructure/Security/SkorubaUserService.cs @@ -6,14 +6,14 @@ namespace PostFundManagement.Infrastructure.Security; public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkorubaUserService { - public async Task> CreateUserAsync(CreateUserRequest request, Guid userId, CancellationToken cancellationToken = default) => + public async Task> CreateUserAsync(CreateUserRequest request, CancellationToken cancellationToken = default) => await Result.Try((Func>>)(async () => { var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); var response = await httpClient.PostAsJsonAsync("api/users", request, cancellationToken); if (!response.IsSuccessStatusCode) - return Result.Fail(CreateError.Create("Failed to create user.")); + return Result.Fail(CreateError.Create(response.ReasonPhrase!)); var created = await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken); @@ -72,9 +72,9 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba await Result.Try((Func>)(async () => { var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var payload = new { UserId = userId, ClaimType = claimType, ClaimValue = claimValue }; + var payload = new { userId = userId, claimType = claimType, claimValue = claimValue }; - var response = await httpClient.PostAsJsonAsync($"api/users/{userId}/claims", payload, cancellationToken); + var response = await httpClient.PostAsJsonAsync($"api/users/claims", payload, cancellationToken); return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to add user claim.")); })); @@ -83,9 +83,12 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba await Result.Try((Func>)(async () => { var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var response = await httpClient.DeleteAsync($"api/users/{userId}/claims/{claimId}", cancellationToken); + var response = await httpClient.DeleteAsync($"api/users/{userId}/Claims?claimId={claimId}", cancellationToken); - return Result.OkIf(response.IsSuccessStatusCode, CreateError.Create("Failed to remove user claim.")); + if(response.StatusCode == System.Net.HttpStatusCode.NotFound) + return Result.Fail(NotFoundError.Create($"Claim {claimId} for user {userId} not found.")); + + return Result.OkIf(response.IsSuccessStatusCode, ValidationError.Create("Failed to remove user claim.")); })); public async Task> GetUserClaimsAsync(Guid userId, int page = 1, int pageSize = 50, CancellationToken cancellationToken = default) => @@ -103,7 +106,7 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba await Result.Try((Func>)(async () => { var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); - var payload = new { UserId = userId, RoleId = roleId }; + var payload = new { userId = userId, roleId = roleId }; var response = await httpClient.PostAsJsonAsync($"api/users/roles", payload, cancellationToken); @@ -183,4 +186,15 @@ public class SkorubaUserService(IHttpClientFactory httpClientFactory) : ISkoruba return Result.FailIf(result is null, NotFoundError.Create("Available roles could not be retrieved.")) .ToResult(result?.Roles?.ToArray() ?? []); })); + + public async Task RemoveUserAsync(Guid userId, CancellationToken cancellationToken = default) => + await Result.Try((Func>)(async () => + { + var httpClient = httpClientFactory.CreateClient(SkorubaHttpClient); + var result = await httpClient.DeleteAsync($"api/users/{userId}", cancellationToken); + + return result.StatusCode == System.Net.HttpStatusCode.NotFound + ? Result.Fail(NotFoundError.Create($"User {userId} not found.")) + : Result.OkIf(result.IsSuccessStatusCode, UpdateError.Create("Failed to remove user.")); + })); } \ No newline at end of file diff --git a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs index 6df913d..e6dea26 100644 --- a/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs +++ b/PostFundManagement.Tests/SkorubaUserServiceIntegrationTests.cs @@ -1,22 +1,11 @@ using PostFundManagement.Application.Extensions; using PostFundManagement.Domain.Abstractions; +using PostFundManagement.Domain.Models.Security; using PostFundManagement.Infrastructure.Database.Services; using static PostFundManagement.Domain.Extensions.Constants; namespace PostFundManagement.Tests; -/// -/// Integration tests for SkorubaUserService.GetUserRolesAsync method. -/// -/// These tests hit the actual Skoruba API environment. -/// Requires the following configuration: -/// - MachineIdentitySettings with valid ClientId and ClientSecret from user secrets -/// - SkorubaApi connection string pointing to the API endpoint -/// - Network access to the Skoruba API -/// -/// To run these tests: -/// dotnet test --filter "FullyQualifiedName~SkorubaUserServiceGetUserRolesIntegrationTests" -/// public class SkorubaUserServiceGetUserRolesIntegrationTests { private readonly ISkorubaUserService _skorubaService; @@ -51,9 +40,6 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests _httpClientFactory = serviceProvider.GetRequiredService(); } - /// - /// Integration test: Verify HttpClient is properly configured with SkorubaHttpClient name. - /// [DebugOnlyFact] public void HttpClientFactory_HasSkorubaHttpClientConfigured() { @@ -65,15 +51,72 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests Assert.NotNull(httpClient.BaseAddress); } - /// - /// Integration test: Verify that the service properly formats API requests. - /// Uses a fake/invalid user ID to test the HTTP request flow. - /// + [DebugOnlyFact] + public async Task CreateUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var newUser = new CreateUserRequest + { + UserName = "testuser", + Email = "testuser@example.com", + EmailConfirmed = true, + }; + + // Act + var result = await _skorubaService.CreateUserAsync(newUser); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task DeleteUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("3b001832-c78d-4705-9bc2-0f2f2ebb35b7"); + + // Act + var result = await _skorubaService.RemoveUserAsync(userId); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task LockoutUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + + // Act + var result = await _skorubaService.SetUserLockoutAsync(userId, true); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task UnlockUserAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + + // Act + var result = await _skorubaService.SetUserLockoutAsync(userId, false); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + [DebugOnlyFact] public async Task GetUserRolesAsync_SendsProperlyFormattedRequest() { // Arrange - var userId = Guid.Parse("6059f1e4-6a41-4447-a546-86ece5102004"); + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); var page = 1; var pageSize = 25; @@ -85,9 +128,88 @@ public class SkorubaUserServiceGetUserRolesIntegrationTests Assert.Empty(result.Errors); } - /// - /// Integration test: Verify cancellation token is respected. - /// + [DebugOnlyFact] + public async Task AddUserRoleAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var roleId = Guid.Parse("34b03edc-cda4-4380-b7a5-3310933b75ab"); // Contributor role ID + + // Act + var result = await _skorubaService.AddRoleAsync(userId, roleId); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task RemoveUserRoleAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var roleId = Guid.Parse("34b03edc-cda4-4380-b7a5-3310933b75ab"); // Contributor role ID + + // Act + var result = await _skorubaService.RemoveRoleAsync(userId, roleId); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task GetUserClaimAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var page = 1; + var pageSize = 25; + + // Act + var result = await _skorubaService.GetUserClaimsAsync(userId, page, pageSize); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task AddUserClaimAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var claimType = "test-claim"; + var claimValue = "test-value"; + + // Act + var result = await _skorubaService.AddClaimAsync(userId, claimType, claimValue); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + + [DebugOnlyFact] + public async Task RemoveUserClaimAsync_MustSucced_WithErrorMessage() + { + // Arrange + var userId = Guid.Parse("285df6e4-c0f9-4c7c-8da7-b3867ffe1880"); + var claimType = "test-claim"; + + var userClaimsResult = await _skorubaService.GetUserClaimsAsync(userId); + var matchingClaim = userClaimsResult.Value?.FirstOrDefault(c => c.ClaimType == claimType); + + Assert.NotNull(matchingClaim); + + // Act + var result = await _skorubaService.RemoveClaimAsync(userId, matchingClaim!.ClaimId!.Value); + + // Assert + Assert.True(result.IsSuccess, result.Errors.FirstOrDefault()?.Message); + Assert.Empty(result.Errors); + } + [DebugOnlyFact] public async Task GetUserRolesAsync_RespectsCancellationToken() { diff --git a/PostFundManagement.slnx b/PostFundManagement.slnx index c829b6c..169329b 100644 --- a/PostFundManagement.slnx +++ b/PostFundManagement.slnx @@ -7,11 +7,9 @@ - - - + From c3cc21f334953d0f867b5d39a9f13d6d31b63bf1 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 11 Oct 2026 07:49:38 +0200 Subject: [PATCH 10/10] Refactored docker compose --- docker-compose.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 16592c8..cd0643d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,12 @@ services: - SecuritySettings__ClientId=${SECURITY_CLIENT_ID} - SecuritySettings__ClientSecret=${SECURITY_CLIENT_SECRET} + # Skoruba Duende Administration Security Overrides + - MachineIdentitySettings__Authority=${ADMIN_SECURITY_AUTHORITY:-https://sts.security.khongisa.co.za} + - MachineIdentitySettings__Scope=${ADMIN_SECURITY_AUDIENCE} + - MachineIdentitySettings__ClientId=${ADMIN_SECURITY_CLIENT_ID} + - MachineIdentitySettings__ClientSecret=${ADMIN_SECURITY_CLIENT_SECRET} + # Data Protection Overrides - DataProtection__Certificate=${DATA_PROTECTION_CERTIFICATE} - DataProtection__Password=${DATA_PROTECTION_CERTIFICATE_PASSWORD}