Compare commits
106
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0338737385 | ||
|
|
82c0936b4c | ||
|
|
5d2a886f6f | ||
|
|
dc4047ca6d | ||
|
|
46fe14d9ef | ||
|
|
f17368d939 | ||
|
|
7aea3fa8de | ||
|
|
d43eb17aa3 | ||
|
|
01547d8c3f | ||
|
|
18dd9131cb | ||
|
|
f82a5cef76 | ||
|
|
614730caab | ||
|
|
9823cd7ea6 | ||
|
|
a7a68fc290 | ||
|
|
4dbc74e488 | ||
|
|
d658497545 | ||
|
|
b947959724 | ||
|
|
58126e7573 | ||
|
|
2fede443cc | ||
|
|
80f220fcae | ||
|
|
06e2c3ee6a | ||
|
|
3c0fd8844c | ||
|
|
b7c135f0fc | ||
|
|
db053e3e5f | ||
|
|
d7177e1a72 | ||
|
|
c67041faea | ||
|
|
0e8a5e1169 | ||
|
|
41fdb067fe | ||
|
|
b4b687dfcc | ||
|
|
f200ccbf60 | ||
|
|
27f57150e1 | ||
|
|
79c63107e9 | ||
|
|
d945731252 | ||
|
|
c979a4632e | ||
|
|
9eed3cff6b | ||
|
|
6db1a2f367 | ||
|
|
06d9952cd7 | ||
|
|
92d481f75d | ||
|
|
1c36602995 | ||
|
|
5ae0c500ac | ||
|
|
db04f800e9 | ||
|
|
e7a19611f0 | ||
|
|
5ad24da7cf | ||
|
|
156dae40b7 | ||
|
|
1b67d9cf8b | ||
|
|
1bd05e64e5 | ||
|
|
303dba3c6f | ||
|
|
1dd4f54a1d | ||
|
|
fae1e080c4 | ||
|
|
4de23d27b3 | ||
|
|
d4bce12dbb | ||
|
|
299b876e1c | ||
|
|
dde1dbe056 | ||
|
|
b81e6feb45 | ||
|
|
4138a1941f | ||
|
|
17af31d810 | ||
|
|
b85cf6a1cb | ||
|
|
81ddc11746 | ||
|
|
5b94672ff5 | ||
|
|
c535392ef1 | ||
|
|
0607de1802 | ||
|
|
4c1e52e452 | ||
|
|
2414d74d1c | ||
|
|
93d9661a7f | ||
|
|
dba401fe94 | ||
|
|
42d73fe6cb | ||
|
|
1475887a7f | ||
|
|
730664d9c4 | ||
|
|
f38e569a34 | ||
|
|
7e79171f97 | ||
|
|
d7b868f2c1 | ||
|
|
d43a09b371 | ||
|
|
0dc0de1502 | ||
|
|
de47dd4a4f | ||
|
|
2810cc669b | ||
|
|
734af8c86f | ||
|
|
a754c42d14 | ||
|
|
bd7ca9372f | ||
|
|
0d01d91ab4 | ||
|
|
2c817a8818 | ||
|
|
4c3a96917b | ||
|
|
e5c3a75795 | ||
|
|
1bc7e65960 | ||
|
|
094126d84b | ||
|
|
2506241a25 | ||
|
|
cfe3530639 | ||
|
|
985557bee4 | ||
|
|
f0b8b3051a | ||
|
|
6c88b9e533 | ||
|
|
7d67408d2c | ||
|
|
d1d58a6183 | ||
|
|
60ad154841 | ||
|
|
2c13170859 | ||
|
|
d87c8aa3c9 | ||
|
|
6af7815ad1 | ||
|
|
a169f6c3f6 | ||
|
|
65ea753c19 | ||
|
|
e6d2663265 | ||
|
|
91b5814b60 | ||
|
|
0c4c848568 | ||
|
|
fb05150ebf | ||
|
|
2f9c20020b | ||
|
|
a771957db3 | ||
|
|
46267a2a34 | ||
|
|
a7f360cc2a | ||
|
|
67c08b40ca |
-192
@@ -1,192 +0,0 @@
|
||||
# PostFundManagement (PFM) Platform — Architectural Specification
|
||||
|
||||
> **Document Version**: 2.0
|
||||
> **Target Runtimes**: .NET 10.0 (C# 13) | React 19 / TypeScript 5.8 / Vite
|
||||
> **Scope**: System Architecture, Security Topology, RBAC Enforcement, and Maker-Checker Pattern
|
||||
|
||||
---
|
||||
|
||||
## 1. System Topology & Architectural Layers
|
||||
|
||||
The PFM platform is constructed using **Clean Architecture** and **Domain-Driven Design (DDD)** principles to guarantee strict decoupling of business rules, persistence concerns, and user interfaces.
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────────┐
|
||||
│ PRESENTATION TIER │
|
||||
│ PostFundManagement.ConsoleUI │ PostFundManagement.PartnerUI │
|
||||
│ (Internal Staff & Governance) │ (External Recipient Portal) │
|
||||
│ React 19 + TypeScript + Vite │ React 19 + WebGL (OGL) + Vite │
|
||||
└───────────────────────────────────┬────────────────────────────────────┘
|
||||
│ HTTPS / REST (v1/api/*) + OIDC PKCE
|
||||
┌───────────────────────────────────▼────────────────────────────────────┐
|
||||
│ API GATEWAY │
|
||||
│ PostFundManagement.Api (ASP.NET Core Minimal APIs / Carter) │
|
||||
│ Authentication: JWT Bearer + OpenTelemetry Observability │
|
||||
└───────────────────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
┌───────────────────────────────────▼────────────────────────────────────┐
|
||||
│ APPLICATION LAYER │
|
||||
│ PostFundManagement.Application │
|
||||
│ CQRS (Mediator), Business Validators, Domain Services, Quartz Jobs │
|
||||
└──────────────────┬─────────────────────────────────┬───────────────────┘
|
||||
│ │
|
||||
┌──────────────────▼──────────────────┐ ┌──────────▼───────────────────┐
|
||||
│ DOMAIN LAYER │ │ INFRASTRUCTURE LAYER │
|
||||
│ PostFundManagement.Domain │ │ PostFundManagement.Infrastr.│
|
||||
│ Entities, Value Objects, Enums, │ │ PostgreSQL (EF Core 10), │
|
||||
│ Domain Invariants, Audit Models │ │ Skoruba STS, S3 Garage, │
|
||||
└─────────────────────────────────────┘ │ Redis HybridCache │
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Security & Identity Architecture
|
||||
|
||||
Authentication and authorization are separated cleanly across system boundaries:
|
||||
|
||||
* **Security Token Service (STS)**: Duende IdentityServer / Skoruba Administration (`https://sts.security.khongisa.co.za`) issues cryptographically signed JWT access tokens using OpenID Connect (OIDC) with Proof Key for Code Exchange (PKCE).
|
||||
* **Audience & Scopes**: Web clients request standard OIDC scopes (`openid`, `profile`, `roles`, `email`, `address`) along with the target API resource scope (`pfm-api-dev`).
|
||||
* **Tenant Isolation**: Every authenticated principal carries a `tenant_id` claim. Multitenant query filters in EF Core enforce cross-tenant partition boundaries at the data access layer.
|
||||
* **Partner Isolation**: Grantees and external recipients possess the `partner` role. The `ConsoleUI` enforces immediate lockout for `partner` roles, restricting external users exclusively to `PartnerUI`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Role-Based Access Control (RBAC) Architecture
|
||||
|
||||
PFM implements a fine-grained, claim-based RBAC model where system permissions are decomposed into **15 operational domains** and **5 progressive action capabilities**.
|
||||
|
||||
### 3.1 Role Claims Inventory
|
||||
|
||||
| Claim Key | Operational Domain | Functional Scope |
|
||||
| :--- | :--- | :--- |
|
||||
| `dashboard` | Executive Dashboard | Macro portfolio KPIs, disbursed capital, and ISO 31000 risk heatmap |
|
||||
| `governance` | Governance & Structure | Holding entities, funder portfolios, programmes, rules, and instruments |
|
||||
| `projects_milestones` | Projects & Milestones | Work breakdown structure (WBS), contractual milestones, and activities |
|
||||
| `grant_financials` | Grants & Financials | Statutory funding awards, budget lines, contracts, and disbursement tranches |
|
||||
| `evidence_risks` | M&E, Evidence & Risks | Deliverable evidence verification queue, indicators, and risk registers |
|
||||
| `beneficiaries` | Beneficiaries & Impact | Demographic targets, POPIA compliance items, and outcome deliverables |
|
||||
| `change_management` | Change Management | Project issues, contractual change requests, and budget variations |
|
||||
| `site_visits` | Site Visits | Physical field inspections, checklist observations, and inspector findings |
|
||||
| `settings_invites` | Settings Invites | Onboarding invitations and candidate notifications dispatch |
|
||||
| `settings_users` | Settings Users | User provisioning, role assignments, and account lockouts |
|
||||
| `settings_auditlog` | Settings Audit Log | Immutable audit ledger and system telemetry records |
|
||||
| `settings_notifications`| Settings Notifications | SMTP engines, notification channels, and dispatch telemetry |
|
||||
| `tenant_self_service` | Tenant Self-Service | Tenant profile configuration and delegated sub-user management |
|
||||
| `tenant_management` | Tenant Management | Multi-tenant directory, partition allocation, and solution ownership |
|
||||
| `unrestricted` | System Administration | Root administrative bypass across all system partitions |
|
||||
|
||||
### 3.2 Claim Actions & Capability Hierarchy
|
||||
|
||||
Action capabilities within a claim domain follow a strict subset hierarchy:
|
||||
|
||||
$$\text{view} \subset \text{add} \subset \text{update} \quad \text{and} \quad \text{view} \subset \text{export}$$
|
||||
|
||||
* **`view`**: Read-only access to entity lists, detailed records, metrics, and progress scores.
|
||||
* **`add`**: Can create new records, edit draft records, submit milestone evidence, and change workflow statuses *other than approval* (includes `view`).
|
||||
* **`update`**: Authoritative governance capability. Can execute **approval** status transitions (`Approved`, `Active` contracts) on records (includes `view` and `add`).
|
||||
* **`export`**: Can generate and download structured spreadsheets (`.xlsx`) and formal PDF reports (includes `view`).
|
||||
* **`all`**: Comprehensive authority (`view`, `add`, `update`, `export`) over the claim domain.
|
||||
|
||||
### 3.3 Authoritative Role-to-Claims Matrix
|
||||
|
||||
| Role | Assigned Claim Domains | Standard Capabilities | Record Approval Authority (`update`) |
|
||||
| :--- | :--- | :--- | :---: |
|
||||
| **`Admin`** | `unrestricted` | `all` | **Yes (System-wide)** |
|
||||
| **`Executive`** | `dashboard`, `governance`, `projects_milestones`, `grant_financials`, `evidence_risks`, `tenant_self_service` | `all` | **Yes** |
|
||||
| **`Manager`** | `dashboard`, `projects_milestones`, `grant_financials`, `evidence_risks`, `beneficiaries`, `change_management`, `site_visits`, `settings_invites`, `settings_users`, `settings_auditlog`, `settings_notifications`, `tenant_self_service` | `all` | **Yes** |
|
||||
| **`Supervisor`** | `dashboard`, `projects_milestones`, `grant_financials`, `evidence_risks`, `beneficiaries`, `change_management`, `site_visits`, `settings_invites`, `settings_users` | `view, add, update, export`<br>*(Dashboard: `view, export`)* | **Yes** |
|
||||
| **`Contributor`** | `projects_milestones`, `grant_financials`, `evidence_risks`, `beneficiaries`, `change_management`, `site_visits`, `settings_invites` | **`view, add`** | ❌ **Strictly Prohibited** |
|
||||
|
||||
---
|
||||
|
||||
## 4. Maker-Checker Pattern Architecture
|
||||
|
||||
To eliminate fraud risk, self-dealing, and conflicts of interest, PFM enforces the **Maker-Checker Pattern** (Segregation of Duties / Dual Authorization).
|
||||
|
||||
### 4.1 Core Principle
|
||||
> **The user who creates or drafts a record (the "Maker") is strictly prohibited from verifying or approving that record (the "Checker"), regardless of their administrative role or RBAC claim privileges.**
|
||||
|
||||
Even if an `Executive`, `Manager`, or `Supervisor` possesses the `update` claim action on a domain, they cannot approve a record if they are identified as the record's creator.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Maker (User A)<br/>Creates Record"] --> B["Record Persisted<br/>with createdBy = User A"]
|
||||
B --> C{"Checker Evaluation<br/>(Approver Login)"}
|
||||
C -->|Checker == User A| D["Approval BLOCKED<br/>Maker-Checker Violation"]
|
||||
C -->|Checker == User B<br/>with 'update' claim| E["Approval GRANTED<br/>Status -> Approved"]
|
||||
```
|
||||
|
||||
### 4.2 Record Attribution Model
|
||||
Every operational domain entity immutably captures the creator identity:
|
||||
* `createdBy`: Cryptographic user identifier (Guid / Subject ID) populated from the verified token claim `context.GetUserId()` upon creation.
|
||||
* `approvedBy`: User identifier of the independent verifier populated upon successful transition to `Approved`.
|
||||
|
||||
### 4.3 Client-Side Enforcement Hooks & Helpers
|
||||
In `PostFundManagement.ConsoleUI`, the Maker-Checker rule is evaluated dynamically via [`useRbac()`](file:///c:/Users/Admin/source/repos/PostFundManagement/PostFundManagement.ConsoleUI/src/auth/rbac.ts):
|
||||
|
||||
* **`isMaker(createdBy)`**: Compares `createdBy` against current user `user.id`, `sub`, and `user.email`.
|
||||
* **`canApproveRecord(claim, createdBy)`**: Evaluates:
|
||||
$$\text{canApproveRecord} = \text{canApprove}(\text{claim}) \land \neg\text{isMaker}(\text{createdBy})$$
|
||||
* **`getApprovalRestrictionReason(claim, createdBy)`**: Surfaces explanatory feedback:
|
||||
- `"Requires update/approval permission"` if the claim lacks `update`.
|
||||
- `"Maker-Checker policy: Record creators cannot approve their own records"` if `isMaker` is true.
|
||||
|
||||
### 4.4 UI Guard Implementations
|
||||
1. **Status Dropdowns**: The `Approved` option in status `<select>` controls is disabled with contextual labels:
|
||||
```tsx
|
||||
<option value={ApprovalStatus.Approved} disabled={!canApproveRecord('projects_milestones', record.createdBy)}>
|
||||
Approved {isMaker(record.createdBy) ? '(Maker-Checker: Cannot approve own record)' : ''}
|
||||
</option>
|
||||
```
|
||||
2. **Action Buttons**: Fast-track "Approve" buttons (e.g. Budget Approval, Disbursement Authorisation, Evidence Review) are hidden or accompanied by a Maker-Checker indicator badge when viewed by the creator.
|
||||
3. **Export Controls**: `<ExportButton>` enforces domain claim checks explicitly (`claim="grant_financials"`), rejecting unauthenticated exports.
|
||||
|
||||
---
|
||||
|
||||
## 5. Caching Strategy, Mutation Versioning & Performance Optimization
|
||||
|
||||
To achieve sub-50ms page transitions while guaranteeing data freshness across mutations in a distributed architecture, PFM employs a multi-tiered caching topology.
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────────────────┐
|
||||
│ REACT QUERY CACHE (In-Memory Browser Tier) │
|
||||
│ staleTime: 2m (dynamic) | 5m (taxonomy) | gcTime: 10m │
|
||||
└───────────────────────────────────┬────────────────────────────────────┘
|
||||
│ Cache Miss / Background Refetch
|
||||
┌───────────────────────────────────▼────────────────────────────────────┐
|
||||
│ AXIOS CLIENT INTERCEPTOR & MUTATION VERSIONING (_v) │
|
||||
│ Reads/Browsing: attaches active `_v` epoch token │
|
||||
│ Mutations (POST/PUT/PATCH/DELETE): auto-bumps epoch -> new `_v` token │
|
||||
└───────────────────────────────────┬────────────────────────────────────┘
|
||||
│ HTTP GET /v1/api/*?_v=<epoch>
|
||||
┌───────────────────────────────────▼────────────────────────────────────┐
|
||||
│ ASP.NET CORE OUTPUTCACHE (Redis / Memory Tier) │
|
||||
│ Base Policy: 2-minute expiration partitioned by URI + QueryString │
|
||||
│ Hits same `_v` -> 2ms response | New `_v` -> DB query & cache refresh │
|
||||
└────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.1 The OutputCache Stale Data Challenge
|
||||
ASP.NET Core Minimal APIs in `PostFundManagement.Api` attach `.CacheOutput()` to GET endpoints, using a 2-minute base sliding expiration backed by Redis / Memory cache.
|
||||
|
||||
Because OutputCache keys are generated from the HTTP Method, Host, Path, and **Query String**, a naive client refetch after a mutation (e.g. `queryClient.invalidateQueries({ queryKey: ['projects'] })`) calls `GET /v1/api/projects`. OutputCache intercepts this identical URI, returning the pre-mutation response cached earlier. The updated project status or approved milestone does not reflect in the UI until the 2-minute cache expires.
|
||||
|
||||
### 5.2 Client-Side Mutation Epoch Versioning
|
||||
PFM solves this without modifying backend endpoints via **Client-Side Mutation Versioning**:
|
||||
1. **Epoch Tracking (`activeMutationEpoch`)**: `httpClient.ts` tracks an active mutation timestamp initialized from `sessionStorage` or `Date.now()`.
|
||||
2. **Automatic Mutation Interceptor**: Every successful mutating HTTP response (`POST`, `PUT`, `PATCH`, `DELETE` with HTTP 2xx) triggers `bumpMutationEpoch()`.
|
||||
3. **Query Parameter Injection**: Outgoing `GET` requests to internal APIs automatically append `_v: getMutationEpoch()`.
|
||||
4. **Instant Invalidation**: When a mutation succeeds, the epoch is bumped. Subsequent React Query refetches send the new `_v`, producing an immediate **cache miss** in ASP.NET Core OutputCache. The backend queries PostgreSQL, returns fresh data, and caches the new state under the new `_v` key.
|
||||
5. **Cache Hit Snappiness**: Navigations between pages while no mutations have occurred reuse the stable `_v`, yielding sub-5ms responses from Redis/Memory OutputCache and 0ms from React Query in-memory cache.
|
||||
6. **Explicit Freshness (`_t`)**: When `Cache-Control: no-cache` is specified or during explicit refresh operations, a unique timestamp `_t` is attached to force a guaranteed fresh fetch.
|
||||
|
||||
### 5.3 RBAC Startup Pipeline Acceleration
|
||||
Following the introduction of fine-grained RBAC and Maker-Checker checks, startup performance was streamlined to eliminate sequential network waterfalls:
|
||||
* **Cache-First Role Claims**: `fetchAndCacheSystemRoles` and `fetchAndCacheRoleClaims` check in-memory and `localStorage` caches *before* dispatching network calls.
|
||||
* **Parallel User Resolution**: `getUserRolesFromApi` and `getUserClaimsFromApi` are resolved concurrently using `Promise.allSettled`.
|
||||
* **Parallel Claim Resolution**: Claims across all assigned roles are retrieved concurrently rather than in serial loops.
|
||||
* **Immediate Non-Blocking Session Render**: If valid session tokens and user profiles exist in `localStorage`, `AuthProvider` immediately unblocks UI rendering (`isLoading: false`) and runs tenant lockout checks, account synchronization, and claim revalidation asynchronously in the background.
|
||||
* **In-Memory User Sync & Lockout Caching**: `isUserSyncedInBrowser` and `verifyTenantLockout` maintain in-memory references to eliminate synchronous `JSON.parse` operations from the request pipeline.
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<NoWarn>$(NoWarn);1701;1702;MA0048;MA0051;AV0029;AV0030</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Assembly signing and licensing for non-test projects -->
|
||||
<PropertyGroup Condition="!$(MSBuildProjectName.EndsWith('Tests'))">
|
||||
<SignAssembly>true</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)PostFundManagement.snk</AssemblyOriginatorKeyFile>
|
||||
<PackageLicenseFile>$(MSBuildThisFileDirectory)LICENSE</PackageLicenseFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Centralized Common Usings across solution -->
|
||||
<ItemGroup>
|
||||
<!-- System & BCL -->
|
||||
<Using Include="System.Collections.ObjectModel" />
|
||||
<Using Include="System.ComponentModel.DataAnnotations" />
|
||||
<Using Include="System.Globalization" />
|
||||
<Using Include="System.Net" />
|
||||
<Using Include="System.Reflection" />
|
||||
<Using Include="System.Security.Cryptography" />
|
||||
<Using Include="System.Security.Cryptography.X509Certificates" />
|
||||
<Using Include="System.Text" />
|
||||
<Using Include="System.Text.Json" />
|
||||
<Using Include="System.Text.Json.Serialization" />
|
||||
<Using Include="System.Text.RegularExpressions" />
|
||||
<Using Include="System.Threading.Channels" />
|
||||
<Using Include="System.Web" />
|
||||
|
||||
<!-- Microsoft Extensions & Web Core -->
|
||||
<Using Include="Microsoft.AspNetCore.Builder" />
|
||||
<Using Include="Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage" />
|
||||
<Using Include="Microsoft.AspNetCore.DataProtection" />
|
||||
<Using Include="Microsoft.AspNetCore.Http" />
|
||||
<Using Include="Microsoft.AspNetCore.Routing" />
|
||||
<Using Include="Microsoft.Extensions.Configuration" />
|
||||
<Using Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<Using Include="Microsoft.Extensions.DependencyInjection.Extensions" />
|
||||
<Using Include="Microsoft.Extensions.Hosting" />
|
||||
<Using Include="Microsoft.Extensions.Logging" />
|
||||
<Using Include="Microsoft.Extensions.Options" />
|
||||
<Using Include="Microsoft.IdentityModel.Tokens" />
|
||||
|
||||
<!-- Domain Constants -->
|
||||
<Using Static="true" Include="PostFundManagement.Domain.Extensions.Constants" />
|
||||
|
||||
<!-- CQRS, Utilities & Persistence -->
|
||||
<Using Include="FluentResults" />
|
||||
<Using Include="HashidsNet" />
|
||||
<Using Include="Humanizer" />
|
||||
<Using Include="Mediator" />
|
||||
<Using Include="Microsoft.EntityFrameworkCore" />
|
||||
<Using Include="Microsoft.EntityFrameworkCore.Design" />
|
||||
<Using Include="Microsoft.EntityFrameworkCore.Metadata.Builders" />
|
||||
<Using Include="Quartz" />
|
||||
<Using Include="Refit" />
|
||||
|
||||
<!-- API & Documentation -->
|
||||
<Using Include="Asp.Versioning" />
|
||||
<Using Include="Microsoft.AspNetCore.OpenApi" />
|
||||
<Using Include="Microsoft.OpenApi" />
|
||||
<Using Include="Scalar.AspNetCore" />
|
||||
|
||||
<!-- Authentication -->
|
||||
<Using Include="IdentityModel.AspNetCore.OAuth2Introspection" />
|
||||
<Using Include="Microsoft.AspNetCore.Authentication" />
|
||||
<Using Include="Microsoft.AspNetCore.Authentication.Cookies" />
|
||||
<Using Include="Microsoft.AspNetCore.Authentication.JwtBearer" />
|
||||
<Using Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" />
|
||||
|
||||
<!-- Diagnostics & Health -->
|
||||
<Using Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" />
|
||||
<Using Include="Microsoft.Extensions.Diagnostics.HealthChecks" />
|
||||
|
||||
<!-- Messaging & Cloud Storage -->
|
||||
<Using Include="Amazon.Runtime" />
|
||||
<Using Include="Amazon.S3" />
|
||||
<Using Include="Amazon.S3.Model" />
|
||||
<Using Include="MailKit.Net.Smtp" />
|
||||
<Using Include="MimeKit" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Domain-specific Usings (Domain and downstream projects excluding Infrastructure where Claim/Activity/TokenRequest collide) -->
|
||||
<ItemGroup Condition="'$(MSBuildProjectName)' == 'PostFundManagement.Domain'">
|
||||
<Using Include="System.Security.Claims" />
|
||||
<Using Include="AccessTokenClient" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Non-Domain / Non-Infrastructure Usings (Application, Api, Tests) -->
|
||||
<ItemGroup Condition="'$(MSBuildProjectName)' != 'PostFundManagement.Domain' and '$(MSBuildProjectName)' != 'PostFundManagement.Infrastructure'">
|
||||
<Using Include="System.Diagnostics" />
|
||||
<Using Include="System.Security.Claims" />
|
||||
<Using Include="AccessTokenClient" />
|
||||
<Using Static="true" Include="PostFundManagement.Application.Extensions.General" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Core & Utilities -->
|
||||
<PackageVersion Include="Castle.Core.AsyncInterceptor" Version="2.1.0" />
|
||||
<PackageVersion Include="Hashids.net" Version="1.7.0" />
|
||||
<PackageVersion Include="Humanizer" Version="3.0.10" />
|
||||
<PackageVersion Include="Scrutor" Version="7.0.0" />
|
||||
|
||||
<!-- Microsoft Extensions & Configuration -->
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Hybrid" Version="10.10.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.UserSecrets" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Polly" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="10.10.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Validation" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.FeatureManagement.AspNetCore" Version="4.7.0" />
|
||||
|
||||
<!-- Security, Authentication & Identity -->
|
||||
<PackageVersion Include="AccessTokenClient.Extensions" Version="5.1.0" />
|
||||
<PackageVersion Include="Duende.AccessTokenManagement" Version="4.2.0" />
|
||||
<PackageVersion Include="Duende.AccessTokenManagement.OpenIdConnect" Version="4.2.0" />
|
||||
<PackageVersion Include="IdentityModel" Version="6.2.0" />
|
||||
<PackageVersion Include="IdentityModel.AspNetCore" Version="4.3.0" />
|
||||
<PackageVersion Include="IdentityModel.AspNetCore.OAuth2introspection" Version="6.2.0" />
|
||||
<PackageVersion Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
|
||||
<PackageVersion Include="KubernetesClient" Version="19.0.2" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Certificate" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="10.0.12" />
|
||||
|
||||
<!-- Upgraded to latest non-vulnerable version -->
|
||||
<PackageVersion Include="System.Security.Cryptography.Pkcs" Version="10.0.13" />
|
||||
<PackageVersion Include="System.Security.Cryptography.Xml" Version="10.0.13" />
|
||||
|
||||
<!-- Resilience -->
|
||||
<PackageVersion Include="Polly" Version="8.8.0" />
|
||||
<PackageVersion Include="Polly.Extensions" Version="8.8.0" />
|
||||
|
||||
<!-- API, Web & Documentation -->
|
||||
<PackageVersion Include="Asp.Versioning.Abstractions" Version="10.2.1" />
|
||||
<PackageVersion Include="Asp.Versioning.Http" Version="10.2.3" />
|
||||
<PackageVersion Include="Asp.Versioning.Mvc.ApiExplorer" Version="10.2.1" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.OutputCaching.StackExchangeRedis" Version="10.0.12" />
|
||||
<PackageVersion Include="Refit.HttpClientFactory" Version="15.2.0" />
|
||||
<PackageVersion Include="Scalar.AspNetCore" Version="2.17.4" />
|
||||
|
||||
<!-- Database & Entity Framework Core -->
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Abstractions" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Analyzers" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.12" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.12" />
|
||||
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
|
||||
|
||||
<!-- Quartz Scheduler -->
|
||||
<PackageVersion Include="Quartz" Version="4.1.0" />
|
||||
<PackageVersion Include="Quartz.AspNetCore" Version="4.1.0" />
|
||||
<PackageVersion Include="Quartz.Extensions.DependencyInjection" Version="4.1.0" />
|
||||
<PackageVersion Include="Quartz.Plugins" Version="4.1.0" />
|
||||
<PackageVersion Include="Quartz.Plugins.TimeZoneConverter" Version="4.1.0" />
|
||||
<PackageVersion Include="Quartz.Serialization.SystemTextJson" Version="4.1.0" />
|
||||
|
||||
<!-- Health Checks -->
|
||||
<PackageVersion Include="AspNetCore.HealthChecks.NpgSql" Version="9.0.0" />
|
||||
<PackageVersion Include="AspNetCore.HealthChecks.UI" Version="9.0.0" />
|
||||
<PackageVersion Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0" />
|
||||
<PackageVersion Include="AspNetCore.HealthChecks.UI.Core" Version="9.0.0" />
|
||||
<PackageVersion Include="AspNetCore.HealthChecks.UI.Data" Version="9.0.0" />
|
||||
<PackageVersion Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="9.0.0" />
|
||||
|
||||
<!-- Observability & OpenTelemetry -->
|
||||
<PackageVersion Include="OpenTelemetry" Version="1.18.0" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.Console" Version="1.18.0" />
|
||||
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.18.0" />
|
||||
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.18.0" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.18.0" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.18.0" />
|
||||
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.18.0" />
|
||||
|
||||
<!-- Email & Messaging -->
|
||||
<PackageVersion Include="MailKit" Version="4.18.0" />
|
||||
<PackageVersion Include="MimeKit" Version="4.18.0" />
|
||||
|
||||
<!-- CQRS & Mediator -->
|
||||
<PackageVersion Include="FluentResults" Version="4.0.0" />
|
||||
<PackageVersion Include="Mediator.Abstractions" Version="3.0.2" />
|
||||
<PackageVersion Include="Mediator.SourceGenerator" Version="3.0.2" />
|
||||
|
||||
<!-- Cloud Storage -->
|
||||
<PackageVersion Include="AWSSDK.Extensions.NetCore.Setup" Version="4.0.101.4" />
|
||||
<PackageVersion Include="AWSSDK.S3" Version="4.0.103.3" />
|
||||
|
||||
<!-- Analyzers -->
|
||||
<PackageVersion Include="Meziantou.Analyzer" Version="3.0.259" />
|
||||
|
||||
<!-- Testing -->
|
||||
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageVersion Include="xunit" Version="2.9.3" />
|
||||
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.4" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -8,11 +8,7 @@ EXPOSE 8080
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
WORKDIR /src
|
||||
|
||||
# Copy props and csproj files for layer caching
|
||||
COPY ["Directory.Build.props", "./"]
|
||||
COPY ["Directory.Packages.props", "./"]
|
||||
COPY ["PostFundManagement.snk", "./"]
|
||||
COPY ["LICENSE", "./"]
|
||||
# Copy csproj files for layer caching
|
||||
COPY ["PostFundManagement.Api/PostFundManagement.Api.csproj", "PostFundManagement.Api/"]
|
||||
COPY ["PostFundManagement.Application/PostFundManagement.Application.csproj", "PostFundManagement.Application/"]
|
||||
COPY ["PostFundManagement.Domain/PostFundManagement.Domain.csproj", "PostFundManagement.Domain/"]
|
||||
@@ -37,4 +33,4 @@ RUN dotnet publish "PostFundManagement.Api.csproj" -c Release -o /app/publish /p
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "PostFundManagement.Api.dll"]
|
||||
ENTRYPOINT ["dotnet", "PostFundManagement.Api.dll"]
|
||||
@@ -1,36 +0,0 @@
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Application.Services.Communications;
|
||||
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 CreateNotificationEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapPost("api/communications/notifications", async (CreateNotificationRequest request,
|
||||
HttpContext context, ICommunicationsService service, CancellationToken cancellationToken = default) =>
|
||||
await service.CreateNotificationAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Created(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Creates a new in-app or outbound notification record")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(CreateNotificationEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status201Created)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Communications);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Communications;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class GetApplicantInviteEndpoint : IEndpoint
|
||||
await service.GetApplicantInviteAsync(applicantUserId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var invite } => Results.Ok(invite),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
.WithDescription("Gets an applicant's invite")
|
||||
@@ -25,8 +27,8 @@ public sealed class GetApplicantInviteEndpoint : IEndpoint
|
||||
.WithName(typeof(GetApplicantInviteEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Invite>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Communications)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Communications;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class GetApplicantInvitesEndpoint : IEndpoint
|
||||
await service.GetApplicantInvitesAsync(applicantUserId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var invite } => Results.Ok(invite),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
.WithDescription("Gets an applicant's invite list")
|
||||
@@ -25,8 +27,8 @@ public sealed class GetApplicantInvitesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetApplicantInvitesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Invite[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Communications)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
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<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<ValidationError>() => 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<Invite>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Communications)
|
||||
.CacheOutput();
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using static PostFundManagement.Application.Extensions.General;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Communications;
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using static PostFundManagement.Application.Extensions.General;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Communications;
|
||||
|
||||
@@ -12,7 +15,7 @@ public sealed class GetNotificationsEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/communications/notifications/{organisationId}", async (string organisationId,
|
||||
builder.MapGet("api/communications/norifications/{organisationId}", async (string organisationId,
|
||||
ICommunicationsService service, CancellationToken cancellationToken = default) =>
|
||||
await service.GetNotificationsAsync(organisationId, cancellationToken) switch
|
||||
{
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Communications;
|
||||
|
||||
[ApiVersionTarget(1)]
|
||||
public sealed class GetUserNotificationsEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/communications/notifications/user/{userId:guid}", async (Guid userId,
|
||||
ICommunicationsService service, CancellationToken cancellationToken = default) =>
|
||||
await service.GetUserNotificationsAsync(userId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var notifications } => Results.Ok(notifications),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
.WithDescription("Retrieves all notifications targeted at a specific user")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetUserNotificationsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Notification[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Communications)
|
||||
.CacheOutput();
|
||||
|
||||
builder.MapGet("api/communications/notifications/inbox", async (HttpContext context,
|
||||
ICommunicationsService service, CancellationToken cancellationToken = default) =>
|
||||
await service.GetUserNotificationsAsync(context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var notifications } => Results.Ok(notifications),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
.WithDescription("Retrieves all in-app and system notifications targeted at the authenticated caller")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName($"{typeof(GetUserNotificationsEndpoint).ToEndpointName()}Inbox")
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Notification[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Communications)
|
||||
.CacheOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Communications;
|
||||
|
||||
@@ -18,7 +20,6 @@ public sealed class SendInviteEndpoint : IEndpoint
|
||||
await service.SendInviteAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var invite } => Results.Ok(invite),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -28,7 +29,6 @@ public sealed class SendInviteEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Invite>(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Communications);
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Application.Services.Communications;
|
||||
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 UpdateNotificationEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapPut("api/communications/notifications", async (UpdateNotificationRequest request,
|
||||
ICommunicationsService service, CancellationToken cancellationToken = default) =>
|
||||
await service.UpdateNotificationAsync(request, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.NoContent(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Updates a notification status, delivery timestamp, or error state")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(UpdateNotificationEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status204NoContent)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Communications);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Evidence;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateIndicatorEndpoint : IEndpoint
|
||||
await service.CreateIndicatorAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -26,8 +28,8 @@ public class CreateIndicatorEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateIndicatorEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence);
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Evidence;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateMilestoneEndpoint : IEndpoint
|
||||
await service.CreateMilestoneAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -28,7 +30,6 @@ public class CreateMilestoneEndpoint : IEndpoint
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class GetEvidenceEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var evidence } => Results.Ok(evidence),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific evidence record and assiciated file URLs")
|
||||
@@ -25,9 +27,9 @@ public sealed class GetEvidenceEndpoint : IEndpoint
|
||||
.WithName(typeof(GetEvidenceEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Domain.Models.Evidence>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
@@ -17,17 +19,17 @@ public sealed class GetEvidenceUrlEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var evidenceUrl } => Results.Ok(evidenceUrl),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a secure download URL of the evidence file, URL expires (default: 15min)")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetEvidenceUrlEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<string>(StatusCodes.Status200OK)
|
||||
.Produces<string>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetIndicatorEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var indicator } => Results.Ok(indicator),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific indicator.")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetIndicatorEndpoint : IEndpoint
|
||||
.WithName(typeof(GetIndicatorEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Indicator>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Evidence;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Evidence;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class UpdateEvidenceEndpoint : IEndpoint
|
||||
await service.UpdateEvidenceAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -27,9 +29,9 @@ public sealed class UpdateEvidenceEndpoint : IEndpoint
|
||||
.WithName(typeof(UpdateEvidenceEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Evidence);
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Execution;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateDisbursementEndpoint : IEndpoint
|
||||
await service.CreateDisbursementAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
@@ -26,9 +28,9 @@ public class CreateDisbursementEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateDisbursementEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Execution;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateRiskEndpoint : IEndpoint
|
||||
await service.CreateRiskAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -26,9 +28,9 @@ public class CreateRiskEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateRiskEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Execution;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetDisbursementEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var disbursement } => Results.Ok(disbursement),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific disbursement")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetDisbursementEndpoint : IEndpoint
|
||||
.WithName(typeof(GetDisbursementEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Disbursement>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetRiskEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var risk } => Results.Ok(risk),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific risk")
|
||||
@@ -26,8 +28,8 @@ public sealed class GetRiskEndpoint : IEndpoint
|
||||
.WithName(typeof(GetRiskEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Risk>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetRuleEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var rules } => Results.Ok(rules),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific programme rule")
|
||||
@@ -26,8 +28,8 @@ public sealed class GetRuleEndpoint : IEndpoint
|
||||
.WithName(typeof(GetRuleEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Rule>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Execution)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Execution;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Execution;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Execution;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Execution;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
@@ -17,7 +19,6 @@ public sealed class CreateOrganisationEndpoint : IEndpoint
|
||||
await service.CreateOrganisationAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
@@ -16,7 +18,7 @@ public class GetInstrumentsEndpoint : IEndpoint
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetInstrumentsAsync(programmeId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var instruments } => Results.Ok(instruments),
|
||||
{ IsSuccess: true, Value: var instrumenrs } => Results.Ok(instrumenrs),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems()),
|
||||
})
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
@@ -18,7 +20,7 @@ public class GetOrganisationEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var organisation } => Results.Ok(organisation),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get organization profile by ID")
|
||||
@@ -26,9 +28,9 @@ public class GetOrganisationEndpoint : IEndpoint
|
||||
.WithName(typeof(GetOrganisationEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Organisation>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class GetPortfolioEndpoint : IEndpoint
|
||||
await service.GetPortfolioAsync(portfolioIdHash: portfolioId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var portfolio } => Results.Ok(portfolio),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get a specific portfolios")
|
||||
@@ -25,9 +27,9 @@ public sealed class GetPortfolioEndpoint : IEndpoint
|
||||
.WithName(typeof(GetPortfolioEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Portfolio[]>(StatusCodes.Status200OK)
|
||||
.Produces<Portfolio[]>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class GetPortfolioProgrammesEndpoint : IEndpoint
|
||||
await service.GetPortfolioProgrammesAsync(portfolioId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var portfolios } => Results.Ok(portfolios),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -26,9 +28,9 @@ public sealed class GetPortfolioProgrammesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetPortfolioProgrammesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Programme[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
@@ -21,7 +23,7 @@ public sealed class GetTenantEndpoint : IEndpoint
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a single tenant")
|
||||
.WithDescription("Gets system tenants")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetTenantsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
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.Governance;
|
||||
|
||||
[ApiVersionTarget(1)]
|
||||
public sealed class GetTenantOrganisationsEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/governance/tenants/{tenantIdHash}/organisations", async (IGovernanceService service, string tenantIdHash,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetTenantOrganisationsAsync(tenantIdHash, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var tenantOrganisations } => Results.Ok(tenantOrganisations),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets organisations created and managed by one tenant")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetTenantOrganisationsEndpoint).ToEndpointName("Retrieval"))
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<TenantOrganisation[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
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.Governance;
|
||||
|
||||
[ApiVersionTarget(1)]
|
||||
public sealed class GetTenantUsersEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/governance/tenants/{tenantIdHash}/users", async (IGovernanceService service, string tenantIdHash,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetTenantUsersAsync(tenantIdHash, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var tenantUsers } => Results.Ok(tenantUsers),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets users created and managed by one tenant")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetTenantUsersEndpoint).ToEndpointName("Retrieval"))
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<TenantUser[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Governance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Entities;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Governance;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Governance;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Grants;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateAwardEndpoint : IEndpoint
|
||||
await service.CreateAwardAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -28,7 +30,7 @@ public class CreateAwardEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants);
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Grants;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -18,8 +20,8 @@ public class CreateBudgetEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Create a new budget line (M05)")
|
||||
@@ -27,8 +29,8 @@ public class CreateBudgetEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateBudgetEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Grants;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateContractEndpoint : IEndpoint
|
||||
await service.CreateContractAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -27,7 +29,6 @@ public class CreateContractEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Grants);
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Grants;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -18,7 +20,7 @@ public class GetAwardEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var award } => Results.Ok(award),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get award by ID")
|
||||
@@ -28,7 +30,7 @@ public class GetAwardEndpoint : IEndpoint
|
||||
.Produces<Award>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -18,7 +20,7 @@ public class GetBudgetEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var budget } => Results.Ok(budget),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get budget by ID")
|
||||
@@ -26,7 +28,7 @@ public class GetBudgetEndpoint : IEndpoint
|
||||
.WithName(typeof(GetBudgetEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Budget>(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -18,7 +20,7 @@ public class GetContractEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var contract } => Results.Ok(contract),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Get contract by ID")
|
||||
@@ -26,7 +28,7 @@ public class GetContractEndpoint : IEndpoint
|
||||
.WithName(typeof(GetContractEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Contract>(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class GetContractUrlEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var contractUrl} => Results.Ok(contractUrl),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a secure download URL, has expiry period (default 15min)")
|
||||
@@ -27,7 +29,7 @@ public sealed class GetContractUrlEndpoint : IEndpoint
|
||||
.Produces<string>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Application.Services.Grants;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
[ApiVersionTarget(1)]
|
||||
public sealed class UpdateAwardEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapPut("api/grants/awards", async (UpdateAwardRequest request, HttpContext context,
|
||||
IGrantsService service, CancellationToken cancellationToken = default) =>
|
||||
await service.UpdateAwardAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Updates a registered funding award")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(UpdateAwardEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants);
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Grants;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Grants;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class UpdateContractEndpoint : IEndpoint
|
||||
await service.UpdateContractAsync(request, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<UpdateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -28,7 +30,7 @@ public sealed class UpdateContractEndpoint : IEndpoint
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Grants;
|
||||
|
||||
@@ -38,6 +40,7 @@ public sealed class UploadContractEndpoint : IEndpoint
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Grants)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateActivityEndpoint : IEndpoint
|
||||
await service.CreateActivityAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } result => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
@@ -26,7 +28,6 @@ public class CreateActivityEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateActivityEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -12,7 +14,14 @@ public sealed class CreateOutcomeEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapPost("api/projects/beneficiaries/outcomes", HandleCreateAsync)
|
||||
builder.MapPost("api/projects/beneficiaris/outcomes", async (CreateOutcomeRequest request, HttpContext context,
|
||||
IProjectService service, CancellationToken cancellationToken = default) =>
|
||||
await service.CreateOutcomeAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Add a new beneficiary outcome")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(CreateOutcomeEndpoint).ToEndpointName())
|
||||
@@ -22,25 +31,6 @@ public sealed class CreateOutcomeEndpoint : IEndpoint
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
|
||||
builder.MapPost("api/projects/beneficiaris/outcomes", HandleCreateAsync)
|
||||
.WithDescription("Add a new beneficiary outcome (legacy route)")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(CreateOutcomeEndpoint).ToEndpointName("TypoAlias"))
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
}
|
||||
|
||||
private static async Task<IResult> HandleCreateAsync(CreateOutcomeRequest request, HttpContext context,
|
||||
IProjectService service, CancellationToken cancellationToken = default) =>
|
||||
await service.CreateOutcomeAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -17,7 +19,7 @@ public sealed class CreateProgrammeEndpoint : IEndpoint
|
||||
await service.CreateProgrammeAsync(request, userId: context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -27,9 +29,9 @@ public sealed class CreateProgrammeEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateProgrammeEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class CreateProjectEndpoint : IEndpoint
|
||||
await service.CreateProjectAsync(request, context.GetUserId(), cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true } result => Results.Ok(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r when r.HasError<ValidationError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r when r.HasError<CreateError>() => Results.BadRequest(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
@@ -27,9 +29,9 @@ public class CreateProjectEndpoint : IEndpoint
|
||||
.WithName(typeof(CreateProjectEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status400BadRequest)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.WithTags(EndpointTags.Projects);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Application.Services.Projects;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ using PostFundManagement.Application.Extensions;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -17,7 +19,7 @@ public class GetActivityEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var activity } => Results.Ok(activity),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific activity by it's id")
|
||||
@@ -25,9 +27,9 @@ public class GetActivityEndpoint : IEndpoint
|
||||
.WithName(typeof(GetActivityEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Domain.Models.Activity>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -12,13 +14,13 @@ public sealed class GetBeneficiariesEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/projects/{projectId}/beneficiaries", async (string projectId, IProjectService service,
|
||||
builder.MapGet("api/projects/beneficiaries/{projectId}", async (string projectId, IProjectService service,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetBeneficiariesAsync(projectId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var beneficiaries } => Results.Ok(beneficiaries),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project beneficiaries")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetBeneficiariesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetBeneficiariesEndpoint).ToEndpointName("Retrieval"))
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Beneficiary[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetBeneficiaryEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var beneficiary } => Results.Ok(beneficiary),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project beneficiaries")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetBeneficiaryEndpoint : IEndpoint
|
||||
.WithName(typeof(GetBeneficiariesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Beneficiary>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetChangeRequestEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var changeRequest } => Results.Ok(changeRequest),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project change request")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetChangeRequestEndpoint : IEndpoint
|
||||
.WithName(typeof(GetChangeRequestEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ChangeRequest>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -12,13 +14,13 @@ public sealed class GetChangeRequestsEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/projects/{projectId}/changerequests", async (string projectId, IProjectService service,
|
||||
builder.MapGet("api/projects/changerequests/{projectId}", async (string projectId, IProjectService service,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetChangeRequestsAsync(projectId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var changeRequests } => Results.Ok(changeRequests),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project change requests")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetChangeRequestsEndpoint : IEndpoint
|
||||
.WithName(typeof(GetChangeRequestsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ChangeRequest[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetComplianceItemEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var complianceItem } => Results.Ok(complianceItem),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project compliance item")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetComplianceItemEndpoint : IEndpoint
|
||||
.WithName(typeof(GetComplianceItemEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ComplianceItem>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -12,13 +14,13 @@ public sealed class GetComplianceItemsEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/projects/{projectId}/complianceitems", async (string projectId, IProjectService service,
|
||||
builder.MapGet("api/projects/complianceitems/{projectId}", async (string projectId, IProjectService service,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetComplianceItemsAsync(projectId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var complianceItems } => Results.Ok(complianceItems),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project compliance items")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetComplianceItemsEndpoint : IEndpoint
|
||||
.WithName(typeof(GetComplianceItemsEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<ComplianceItem[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -18,7 +20,7 @@ public sealed class GetIssueEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var issue } => Results.Ok(issue),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project issue")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetIssueEndpoint : IEndpoint
|
||||
.WithName(typeof(GetIssueEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Issue>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -12,13 +14,13 @@ public sealed class GetIssuesEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/projects/{projectId}/issues", async (string projectId, IProjectService service,
|
||||
builder.MapGet("api/projects/issues/{projectId}", async (string projectId, IProjectService service,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetIssuesAsync(projectId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var issues } => Results.Ok(issues),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets project issues")
|
||||
@@ -26,9 +28,9 @@ public sealed class GetIssuesEndpoint : IEndpoint
|
||||
.WithName(typeof(GetIssuesEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Issue[]>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Errors;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -18,7 +20,7 @@ public class GetMilestoneEndpoint : IEndpoint
|
||||
{
|
||||
{ IsSuccess: true, Value: var milestone } => Results.Ok(milestone),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific milestone")
|
||||
@@ -26,9 +28,9 @@ public class GetMilestoneEndpoint : IEndpoint
|
||||
.WithName(typeof(GetMilestoneEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Milestone>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
@@ -4,6 +4,8 @@ using PostFundManagement.Domain;
|
||||
using PostFundManagement.Domain.Abstractions;
|
||||
using PostFundManagement.Domain.Extensions;
|
||||
using PostFundManagement.Domain.Models;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using PostFundManagement.Application.Abstractions.Services;
|
||||
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;
|
||||
using PostFundManagement.Domain.Security;
|
||||
using Problems = Microsoft.AspNetCore.Mvc.ProblemDetails;
|
||||
|
||||
namespace PostFundManagement.Api.Endpoints.Projects;
|
||||
|
||||
@@ -12,40 +14,25 @@ public sealed class GetOutcomeEndpoint : IEndpoint
|
||||
{
|
||||
public void Map(IEndpointRouteBuilder builder)
|
||||
{
|
||||
builder.MapGet("api/projects/outcome/{outcomeId}", HandleGetAsync)
|
||||
builder.MapGet("api/projects/outcomes/{outcomeId}", async (string outcomeId, IProjectService service,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetOutcomeAsync(outcomeId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var outcome } => Results.Ok(outcome),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
})
|
||||
.WithDescription("Gets a specific project outcome")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetOutcomeEndpoint).ToEndpointName())
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Outcome>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status404NotFound)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
|
||||
builder.MapGet("api/projects/outcomes/single/{outcomeId}", HandleGetAsync)
|
||||
.WithDescription("Gets a specific project outcome")
|
||||
.RequireAuthorization(Constants.MainScope)
|
||||
.WithName(typeof(GetOutcomeEndpoint).ToEndpointName("Single"))
|
||||
.MapToApiVersion(new ApiVersion(1))
|
||||
.Produces<Outcome>(StatusCodes.Status200OK)
|
||||
.Produces(StatusCodes.Status403Forbidden)
|
||||
.Produces(StatusCodes.Status401Unauthorized)
|
||||
.Produces<Problems>(StatusCodes.Status404NotFound)
|
||||
.Produces<Problems>(StatusCodes.Status500InternalServerError)
|
||||
.WithTags(EndpointTags.Projects)
|
||||
.CacheOutput();
|
||||
}
|
||||
|
||||
private static async Task<IResult> HandleGetAsync(string outcomeId, IProjectService service,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
await service.GetOutcomeAsync(outcomeId, cancellationToken) switch
|
||||
{
|
||||
{ IsSuccess: true, Value: var outcome } => Results.Ok(outcome),
|
||||
var r when r.HasError<IdDecodeError>() => Results.Forbid(),
|
||||
var r when r.HasError<NotFoundError>() => Results.NotFound(r.Errors.ToProblems()),
|
||||
var r => Results.InternalServerError(r.Errors.ToProblems())
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user