From 7bdafd4bf32bcf54f7e505eab0af5972fcda7140 Mon Sep 17 00:00:00 2001 From: Linzi CARLIN Date: Wed, 15 Jul 2026 16:24:01 +0100 Subject: [PATCH 1/3] add appointing body to trust governance response, update readme, add postman collections --- README.md | 18 + ...rsonsAPI-Dev-Test.postman_environment.json | 33 ++ postman/PersonsAPI.postman_collection.json | 400 ++++++++++++++++++ .../Common/Models/TrustGovernance.cs | 1 + .../TrustWithGovernanceProfile.cs | 4 +- .../Generated/Contracts.g.cs | 3 + .../Generated/swagger.json | 4 + .../TrustWithGovernanceProfileTests.cs | 6 +- 8 files changed, 466 insertions(+), 3 deletions(-) create mode 100644 postman/PersonsAPI-Dev-Test.postman_environment.json create mode 100644 postman/PersonsAPI.postman_collection.json diff --git a/README.md b/README.md index 2ea7edc..c3ef52c 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,21 @@ The Persons API is a service that provides contact information and basic persona ## Technologies .NET, JSON, OpenAPI, Web API + +## Authenticating for Swagger + +The Swagger UI requires an authentication token to access the API. You can obtain a token via Postman. Import the Postman collection and environment from the `Postman` folder. +You will need to ask a colleague to provide you with the `Secret` and `ClientId` values. +You should now be able to generate a new access token. You can either call the endpoints in Postman or use the token in the Swagger UI. + +## Running the API locally + +You can run a local instance of the Academies database, or alternatively, you can connect to the Dev or Test instance of the database. + +Replace the "DefaultConnection" string in `appsettings.Development.json` with the appropriate connection string for your environment, e.g. + +`"Server=srv-t1dv-sips.database.windows.net;Database=sip;User Id=;Password="` + +Build and run the application as you usually would. + +Create a token using Postman (see above) and paste it into the Swagger UI, or call your locally hosted endpoints in Postman. \ No newline at end of file diff --git a/postman/PersonsAPI-Dev-Test.postman_environment.json b/postman/PersonsAPI-Dev-Test.postman_environment.json new file mode 100644 index 0000000..e142632 --- /dev/null +++ b/postman/PersonsAPI-Dev-Test.postman_environment.json @@ -0,0 +1,33 @@ +{ + "id": "c5c147b1-8292-409f-8d52-fd17d4c1752a", + "name": "PersonsAPI-Dev-Test", + "values": [ + { + "key": "Secret", + "value": "", + "type": "secret", + "enabled": true + }, + { + "key": "ClientId", + "value": "", + "type": "default", + "enabled": true + }, + { + "key": "Scope", + "value": "api://930a077f-43d0-48cb-9316-1e0430eeaf6b/.default", + "type": "default", + "enabled": true + }, + { + "key": "bearer_token", + "value": "", + "type": "default", + "enabled": true + } + ], + "_postman_variable_scope": "environment", + "_postman_exported_at": "2025-09-24T15:48:03.449Z", + "_postman_exported_using": "Postman/11.62.6" +} \ No newline at end of file diff --git a/postman/PersonsAPI.postman_collection.json b/postman/PersonsAPI.postman_collection.json new file mode 100644 index 0000000..76521df --- /dev/null +++ b/postman/PersonsAPI.postman_collection.json @@ -0,0 +1,400 @@ +{ + "info": { + "_postman_id": "e13d9521-e827-4d43-99a3-05cb5eb87348", + "name": "PersonsAPI", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "37080380" + }, + "item": [ + { + "name": "Dev", + "item": [ + { + "name": "GetMPByConstituency", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184d01-rsd-frontdoor-persons-api-h8cndgfchzh5gjgr.a03.azurefd.net/v1/Constituencies/{{constituencyName}}/mp", + "protocol": "https", + "host": [ + "s184d01-tramsapicdnendpoint-personsapi-a3d9cpcwahc6dnh0", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Constituencies", + "{{constituencyName}}", + "mp" + ] + } + }, + "response": [] + }, + { + "name": "GetMPBySchool", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184d01-rsd-frontdoor-persons-api-h8cndgfchzh5gjgr.a03.azurefd.net/v1/Establishments/{{urn}}/GetMPBySchool", + "protocol": "https", + "host": [ + "s184d01-tramsapicdnendpoint-personsapi-a3d9cpcwahc6dnh0", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Establishments", + "{{urn}}", + "GetMPBySchool" + ] + } + }, + "response": [] + }, + { + "name": "GetAssociatedPersonsWithAcademy", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184d01-rsd-frontdoor-persons-api-h8cndgfchzh5gjgr.a03.azurefd.net/v1/Establishments/{{urn}}/getAssociatedPersons", + "protocol": "https", + "host": [ + "s184d01-tramsapicdnendpoint-personsapi-a3d9cpcwahc6dnh0", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Establishments", + "{{urn}}", + "getAssociatedPersons" + ] + } + }, + "response": [] + }, + { + "name": "GetAssociatedPersonsWithTrust", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184d01-rsd-frontdoor-persons-api-h8cndgfchzh5gjgr.a03.azurefd.net/v1/Trusts/{{trn_ukprn}}/getAssociatedPersons", + "protocol": "https", + "host": [ + "s184d01-tramsapicdnendpoint-personsapi-a3d9cpcwahc6dnh0", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Trusts", + "{{trn_ukprn}}", + "getAssociatedPersons" + ] + } + }, + "response": [] + }, + { + "name": "GetMpsByConstuencies", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"constituencyNames\": [\r\n \"Aberdeen North\",\r\n \"East Ham\",\r\n \"Halifax\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://s184d01-rsd-frontdoor-persons-api-h8cndgfchzh5gjgr.a03.azurefd.net/v1/Constituencies/mps", + "protocol": "https", + "host": [ + "s184d01-tramsapicdnendpoint-personsapi-a3d9cpcwahc6dnh0", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Constituencies", + "mps" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Test", + "item": [ + { + "name": "GetMPByConstituency", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184t01-rsd-frontdoor-persons-api-dueghychhjcrefd2.a01.azurefd.net/v1/Constituencies/{{constituencyName}}/mp", + "protocol": "https", + "host": [ + "s184t01-tramsapicdnendpoint-personsapi-hwcbgdh4a8c2dhb5", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Constituencies", + "{{constituencyName}}", + "mp" + ] + } + }, + "response": [] + }, + { + "name": "GetMPBySchool", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184t01-rsd-frontdoor-persons-api-dueghychhjcrefd2.a01.azurefd.net/v1/Establishments/{{urn}}/GetMPBySchool", + "protocol": "https", + "host": [ + "s184t01-tramsapicdnendpoint-personsapi-hwcbgdh4a8c2dhb5", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Establishments", + "{{urn}}", + "GetMPBySchool" + ] + } + }, + "response": [] + }, + { + "name": "GetAssociatedPersonsWithAcademy", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184t01-rsd-frontdoor-persons-api-dueghychhjcrefd2.a01.azurefd.net/v1/Establishments/{{urn}}/getAssociatedPersons", + "protocol": "https", + "host": [ + "s184t01-tramsapicdnendpoint-personsapi-hwcbgdh4a8c2dhb5", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Establishments", + "{{urn}}", + "getAssociatedPersons" + ] + } + }, + "response": [] + }, + { + "name": "GetAssociatedPersonsWithTrust", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://s184t01-rsd-frontdoor-persons-api-dueghychhjcrefd2.a01.azurefd.net/v1/Trusts/{{trn_ukprn}}/getAssociatedPersons", + "protocol": "https", + "host": [ + "s184t01-tramsapicdnendpoint-personsapi-hwcbgdh4a8c2dhb5", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Trusts", + "{{trn_ukprn}}", + "getAssociatedPersons" + ] + } + }, + "response": [] + }, + { + "name": "GetMpsByConstuencies", + "request": { + "method": "POST", + "header": [], + "body": { + "mode": "raw", + "raw": "{\r\n \"constituencyNames\": [\r\n \"Aberdeen North\",\r\n \"East Ham\",\r\n \"Halifax\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "https://s184t01-rsd-frontdoor-persons-api-dueghychhjcrefd2.a01.azurefd.net/v1/Constituencies/mps", + "protocol": "https", + "host": [ + "s184t01-tramsapicdnendpoint-personsapi-hwcbgdh4a8c2dhb5", + "z01", + "azurefd", + "net" + ], + "path": [ + "v1", + "Constituencies", + "mps" + ] + } + }, + "response": [] + } + ] + } + ], + "auth": { + "type": "oauth2", + "oauth2": [ + { + "key": "tokenType", + "value": "Bearer", + "type": "string" + }, + { + "key": "accessToken", + "value": "", + "type": "string" + }, + { + "key": "refreshRequestParams", + "value": [], + "type": "any" + }, + { + "key": "tokenRequestParams", + "value": [], + "type": "any" + }, + { + "key": "authRequestParams", + "value": [], + "type": "any" + }, + { + "key": "challengeAlgorithm", + "value": "S256", + "type": "string" + }, + { + "key": "useBrowser", + "value": true, + "type": "boolean" + }, + { + "key": "scope", + "value": "{{Scope}}", + "type": "string" + }, + { + "key": "redirect_uri", + "value": "https://oauth.pstmn.io/v1/callback", + "type": "string" + }, + { + "key": "grant_type", + "value": "client_credentials", + "type": "string" + }, + { + "key": "clientSecret", + "value": "{{Secret}}", + "type": "string" + }, + { + "key": "clientId", + "value": "{{ClientId}}", + "type": "string" + }, + { + "key": "authUrl", + "value": "https://login.microsoftonline.com/9c7d9dd3-840c-4b3f-818e-552865082e16/oauth2/v2.0/authorize", + "type": "string" + }, + { + "key": "addTokenTo", + "value": "header", + "type": "string" + }, + { + "key": "client_authentication", + "value": "header", + "type": "string" + }, + { + "key": "accessTokenUrl", + "value": "https://login.microsoftonline.com/9c7d9dd3-840c-4b3f-818e-552865082e16/oauth2/v2.0/token", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "constituencyName", + "value": "Aberdeen North", + "type": "default" + }, + { + "key": "urn", + "value": "100006", + "type": "default" + }, + { + "key": "trn_ukprn", + "value": "TR00020", + "type": "default" + } + ] +} \ No newline at end of file diff --git a/src/Dfe.PersonsApi.Application/Common/Models/TrustGovernance.cs b/src/Dfe.PersonsApi.Application/Common/Models/TrustGovernance.cs index 5ac737a..6456d92 100644 --- a/src/Dfe.PersonsApi.Application/Common/Models/TrustGovernance.cs +++ b/src/Dfe.PersonsApi.Application/Common/Models/TrustGovernance.cs @@ -6,5 +6,6 @@ public class TrustGovernance : Person public string? TRN { get; set; } public string? DateOfAppointment { get; set; } public string? DateTermOfOfficeEndsEnded { get; set; } + public string? AppointingBody { get; set; } } } diff --git a/src/Dfe.PersonsApi.Application/MappingProfiles/TrustWithGovernanceProfile.cs b/src/Dfe.PersonsApi.Application/MappingProfiles/TrustWithGovernanceProfile.cs index 91840a3..89a6556 100644 --- a/src/Dfe.PersonsApi.Application/MappingProfiles/TrustWithGovernanceProfile.cs +++ b/src/Dfe.PersonsApi.Application/MappingProfiles/TrustWithGovernanceProfile.cs @@ -22,8 +22,8 @@ public TrustWithGovernanceProfile() .ForMember(dest => dest.UpdatedAt, opt => opt.MapFrom(src => src.TrustGovernance.Modified)) .ForMember(dest => dest.Phone, opt => opt.Ignore()) .ForMember(dest => dest.DateOfAppointment, opt => opt.MapFrom(src => src.TrustGovernance.DateOfAppointment)) - .ForMember(dest => dest.DateTermOfOfficeEndsEnded, opt => opt.MapFrom(src => src.TrustGovernance.DateTermOfOfficeEndsOrEnded)); - + .ForMember(dest => dest.DateTermOfOfficeEndsEnded, opt => opt.MapFrom(src => src.TrustGovernance.DateTermOfOfficeEndsOrEnded)) + .ForMember(dest => dest.AppointingBody, opt => opt.MapFrom(src => src.TrustGovernance.AppointingBody)); } } } \ No newline at end of file diff --git a/src/GovUK.Dfe.PersonsApi.Client/Generated/Contracts.g.cs b/src/GovUK.Dfe.PersonsApi.Client/Generated/Contracts.g.cs index bcc4fb9..2cf9234 100644 --- a/src/GovUK.Dfe.PersonsApi.Client/Generated/Contracts.g.cs +++ b/src/GovUK.Dfe.PersonsApi.Client/Generated/Contracts.g.cs @@ -257,6 +257,9 @@ public partial class TrustGovernance : Person [Newtonsoft.Json.JsonProperty("dateTermOfOfficeEndsEnded", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string DateTermOfOfficeEndsEnded { get; set; } + [Newtonsoft.Json.JsonProperty("appointingBody", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] + public string AppointingBody { get; set; } + public string ToJson() { diff --git a/src/GovUK.Dfe.PersonsApi.Client/Generated/swagger.json b/src/GovUK.Dfe.PersonsApi.Client/Generated/swagger.json index 159292f..25f9789 100644 --- a/src/GovUK.Dfe.PersonsApi.Client/Generated/swagger.json +++ b/src/GovUK.Dfe.PersonsApi.Client/Generated/swagger.json @@ -331,6 +331,10 @@ "dateTermOfOfficeEndsEnded": { "type": "string", "nullable": true + }, + "appointingBody": { + "type": "string", + "nullable": true } } } diff --git a/src/Tests/Dfe.PersonsApi.Application.Tests/MappingProfiles/TrustWithGovernanceProfileTests.cs b/src/Tests/Dfe.PersonsApi.Application.Tests/MappingProfiles/TrustWithGovernanceProfileTests.cs index ab8e5ac..9b67227 100644 --- a/src/Tests/Dfe.PersonsApi.Application.Tests/MappingProfiles/TrustWithGovernanceProfileTests.cs +++ b/src/Tests/Dfe.PersonsApi.Application.Tests/MappingProfiles/TrustWithGovernanceProfileTests.cs @@ -47,6 +47,7 @@ public void Map_TrustGovernanceQueryModelToTrustGovernance_ShouldMapAllPropertie var expectedUpdatedAt = source.TrustGovernance.Modified; var expectedDateOfAppointment = source.TrustGovernance.DateOfAppointment; var expectedDateTermOfOfficeEndsEnded = source.TrustGovernance.DateTermOfOfficeEndsOrEnded; + var appointingBody = source.TrustGovernance.AppointingBody; // Act var result = _mapper.Map(source); @@ -65,6 +66,7 @@ public void Map_TrustGovernanceQueryModelToTrustGovernance_ShouldMapAllPropertie result.UpdatedAt.Should().Be(expectedUpdatedAt); result.DateOfAppointment.Should().Be(expectedDateOfAppointment); result.DateTermOfOfficeEndsEnded.Should().Be(expectedDateTermOfOfficeEndsEnded); + result.AppointingBody.Should().Be(appointingBody); } [Fact] @@ -87,7 +89,8 @@ public void Map_WhenTrustGovernanceHasNullValues_ShouldHandleNullsCorrectly() Email = null, Modified = null, DateOfAppointment = null, - DateTermOfOfficeEndsOrEnded = null + DateTermOfOfficeEndsOrEnded = null, + AppointingBody = null }; var governanceRoleType = new GovernanceRoleType @@ -116,6 +119,7 @@ public void Map_WhenTrustGovernanceHasNullValues_ShouldHandleNullsCorrectly() result.DateOfAppointment.Should().BeNull(); result.DateTermOfOfficeEndsEnded.Should().BeNull(); result.Phone.Should().BeNull(); + result.AppointingBody.Should().BeNull(); } [Fact] From 688f450612048a24e60e0e015203990fad1205f7 Mon Sep 17 00:00:00 2001 From: Linzi CARLIN Date: Thu, 16 Jul 2026 12:25:43 +0100 Subject: [PATCH 2/3] upgrade gittools actions version --- .github/workflows/pack-template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pack-template.yml b/.github/workflows/pack-template.yml index c45580a..0104d12 100644 --- a/.github/workflows/pack-template.yml +++ b/.github/workflows/pack-template.yml @@ -34,7 +34,7 @@ jobs: dotnet-version: '8.0.x' - name: Install GitVersion (v5) - uses: gittools/actions/gitversion/setup@v0.9 + uses: gittools/actions/gitversion/setup@v4.7.0 with: versionSpec: '5.x' From 8e4126fb1cd1074f099d8d25ffca1a77a03a0b9a Mon Sep 17 00:00:00 2001 From: Linzi CARLIN Date: Thu, 16 Jul 2026 12:32:07 +0100 Subject: [PATCH 3/3] upgrade gitversion version spec --- .github/workflows/pack-template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pack-template.yml b/.github/workflows/pack-template.yml index 0104d12..f647b73 100644 --- a/.github/workflows/pack-template.yml +++ b/.github/workflows/pack-template.yml @@ -36,7 +36,7 @@ jobs: - name: Install GitVersion (v5) uses: gittools/actions/gitversion/setup@v4.7.0 with: - versionSpec: '5.x' + versionSpec: '6.x' - name: Add .NET global tools to PATH run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH