Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 2025-03-10
- [PI-387] Add Product Team Id to search results
- [PI-843] Add Read Product to test UI
- [PI-764] Refine Swagger

## 2025-03-07
- [PI-383] External ID
- [PI-838] product_team includes product_team_id
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2025.03.07
2025.03.10
3 changes: 3 additions & 0 deletions changelog/2025-03-10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- [PI-387] Add Product Team Id to search results
- [PI-843] Add Read Product to test UI
- [PI-764] Refine Swagger
46 changes: 17 additions & 29 deletions infrastructure/swagger/02_info.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,32 @@ info:
description: |
## Overview

API to configure internal systems to allow a Connecting Party to connect. A source of information about Connecting Parties (systems that connect to NHSE) that helps provide system identity attributes that ensure NHSE services know what systems they are connecting to and the legal entities they are sharing data with. This service is driven by APIs that enable self-service for activities such as certificate management and environment access. It also is a store of end-to-end onboarding/integration data and a catalogue of endpoints.
Use this API to access the Connecting Party Manager (CPM) service - an internal service for the creation and management of product IDs.

This API only has a single access mode, application-restricted - signed JWT authentication, through which you may:

* Create a product team
* Create a product
* Retrieve details about a product team
* Retrieve details about a product
* Retrieve a list of all products associated wit a team or all products associated with an organisation, grouped by product team
* Delete a product team
* Delete a product

## Who can use this API

This API can only be used where there is a legal basis to do so. Make sure you have a valid use case before you go too far with your development. You must demonstrate you have a valid use case as part of digital onboarding. Connecting Parties must have an appointed Clinical Safety Officer and undertake a Clinical Safety Assessment.
Currently this API is for [internal use only](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#statuses).

## API status and roadmap

This API is in [development](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#statuses).
This API is in development, meaning:

To see our roadmap, or to suggest, comment or vote on features for this API, see our interactive [product backlog](https://nhs-digital-api-management.featureupvote.com/).

If you have any other queries, [contact us](https://digital.nhs.uk/developer/help-and-support).
* it is available for testing in the integration environment
* we expect to make breaking changes based on developer feedback

## Service level

This API is a platinum service, meaning it is operational and supported 24 hours a day, 365 days a year.
This API is a bronze service, meaning it is operational and supported only during business hours (8 am to 6 pm), Monday to Friday excluding bank holidays.

For more details, see [service levels](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#service-levels).

Expand Down Expand Up @@ -96,28 +105,7 @@ info:

## Onboarding

You need to get your software approved by us before it can go live with this API. We call this onboarding. The onboarding process can sometimes be quite long, so it’s worth planning well ahead.

As part of this process, you need to demonstrate that you can manage risks and that your software conforms technically with the requirements for this API.

Information on this page might impact the design of your software. For details, see [Onboarding support information](https://digital.nhs.uk/developer/api-catalogue/national-record-locator-consumer-fhir/onboarding-support-information).

To understand how our online digital onboarding process works, see [digital onboarding](https://digital.nhs.uk/developer/guides-and-documentation/digital-onboarding#using-the-digital-onboarding-portal).

<div class="nhsd-m-emphasis-box nhsd-m-emphasis-box--emphasis nhsd-!t-margin-bottom-6" aria-label="Highlighted Information">
<div class="nhsd-a-box nhsd-a-box--border-blue">
<div class="nhsd-m-emphasis-box__image-box">
<figure class="nhsd-a-image">
<picture class="nhsd-a-image__picture">
<img src="http://digital.nhs.uk/binaries/content/gallery/icons/play-circle.svg?colour=231f20" alt="" style="object-fit:fill">
</picture>
</figure>
</div>
<div class="nhsd-m-emphasis-box__content-box">
<div data-uipath="website.contentblock.emphasis.content" class="nhsd-t-word-break"><p class="nhsd-t-body">To get started, sign in or create a <a href="http://onboarding.prod.api.platform.nhs.uk/">developer account</a>, then select 'product onboarding'.</p></div>
</div>
</div>
</div>
This API is not yet available for onboarding.

## Change log

Expand Down
14 changes: 7 additions & 7 deletions infrastructure/swagger/05_paths.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ paths:
"200":
$ref: "#/components/responses/StatusOK"
"404":
$ref: "#/components/responses/NotFound"
description: _status not found
parameters:
- $ref: "#/components/parameters/HeaderVersion"
- $ref: "#/components/parameters/HeaderRequestId"
Expand Down Expand Up @@ -128,7 +128,7 @@ paths:
"200":
$ref: "#/components/responses/CPMProductTeamRead"
"404":
$ref: "#/components/responses/NotFound"
$ref: "#/components/responses/ProductTeamNotFound"
x-amazon-apigateway-integration:
<<: *ApiGatewayIntegration
uri: ${method_readProductTeam}
Expand All @@ -151,7 +151,7 @@ paths:
"200":
$ref: "#/components/responses/CpmProductTeamDelete"
"404":
$ref: "#/components/responses/NotFound"
$ref: "#/components/responses/ProductTeamNotFound"
"409":
$ref: "#/components/responses/Conflict"
x-amazon-apigateway-integration:
Expand Down Expand Up @@ -225,9 +225,9 @@ paths:
"201":
$ref: "#/components/responses/ProductCreate"
"400":
$ref: "#/components/responses/BadRequest"
$ref: "#/components/responses/CreateProductBadRequest"
"404":
$ref: "#/components/responses/NotFound"
$ref: "#/components/responses/ProductTeamNotFound"
x-amazon-apigateway-integration:
<<: *ApiGatewayIntegration
uri: ${method_createCpmProduct}
Expand Down Expand Up @@ -356,7 +356,7 @@ paths:
"200":
$ref: "#/components/responses/ProductRead"
"404":
$ref: "#/components/responses/NotFound"
$ref: "#/components/responses/ProductNotFound"
x-amazon-apigateway-integration:
<<: *ApiGatewayIntegration
uri: ${method_readCpmProduct}
Expand Down Expand Up @@ -424,7 +424,7 @@ paths:
"200":
$ref: "#/components/responses/ProductDelete"
"404":
$ref: "#/components/responses/NotFound"
$ref: "#/components/responses/ProductDeleteNotFound"
x-amazon-apigateway-integration:
<<: *ApiGatewayIntegration
uri: ${method_deleteCpmProduct}
Expand Down
22 changes: 13 additions & 9 deletions infrastructure/swagger/07_components--schemas--domain.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ components:
type: string
name:
type: string
cpm_product_team_id:
type: string
product_team_id:
type: string
cpm_product_team_id:
type: string
ods_code:
type: string
status:
Expand Down Expand Up @@ -142,6 +142,8 @@ components:
items:
type: object
properties:
cpm_product_team_id:
type: string
product_team_id:
type: string
products:
Expand Down Expand Up @@ -178,23 +180,25 @@ components:
nullable: true
example:
results:
- org_code: "xyzzy"
- org_code: "F5H1R"
product_teams:
- product_team_id: "1234"
- product_team_id: "55e86121-3826-468c-a6f0-dd0f1fbc0259"
cpm_product_team_id: "a9a9694d-001b-45ce-9f2a-6c9bf80ae0d0"
products:
- id: "P.123"
product_team_id: "1234"
- id: "P.1X3-XYZ"
product_team_id: "55e86121-3826-468c-a6f0-dd0f1fbc0259"
name: "My Great Product 1"
ods_code: "F5H1R"
status: "active"
created_on: "2024-10-15T10:00:00Z"
updated_on: "null"
deleted_on: "null"
keys: []
- product_team_id: "5678"
- product_team_id: "24ac1857-f718-4905-813f-52da930c3ea1"
cpm_product_team_id: "152705aa-0342-487f-a654-64bba814a847"
products:
- id: "P.xyz"
product_team_id: "5678"
- id: "P.4Y6-ABC"
product_team_id: "24ac1857-f718-4905-813f-52da930c3ea1"
name: "My Great Product 3"
ods_code: "F5H1R"
status: "active"
Expand Down
4 changes: 2 additions & 2 deletions infrastructure/swagger/10_components--parameters--path.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ components:
name: product_team_id
in: path
required: true
description: product team identifier
description: Product Team identifier. Either the "internally" generated id (cpm_product_team_id) or the provided team id (product_team_id)
schema:
type: string
ProductId:
name: product_id
in: path
required: true
description: product identifier
description: The Product identifier generated at time of creation.
schema:
type: string
62 changes: 58 additions & 4 deletions infrastructure/swagger/12_components--responses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,43 @@ components:
$ref: "#/components/schemas/StatusOK"
headers:
<<: *ResponseHeaders
NotFound:
description: Not found
ProductTeamNotFound:
description: Product Team has not been found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
errors:
- code: "RESOURCE_NOT_FOUND"
message: "Could not find <ENTITY> for key ('<ID>')"
message: "Could not find ProductTeam for key ('f9518c12-6c83-4544-97db-d9dd1d64da97')"
ProductNotFound:
description: Product has not been found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
example:
errors:
- code: "RESOURCE_NOT_FOUND"
message: "Could not find CpmProduct for key ('P.XXX-YYY')"
ProductDeleteNotFound:
description: Product has not been found
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
ProductTeamNotFound:
value:
errors:
- code: "RESOURCE_NOT_FOUND"
message: "Could not find ProductTeam for key ('f9518c12-6c83-4544-97db-d9dd1d64da97')"
ProductNotFound:
value:
errors:
- code: "RESOURCE_NOT_FOUND"
message: "Could not find CpmProduct for key ('f9518c12-6c83-4544-97db-d9dd1d64da97', 'P.XXX-YYY')"
Conflict:
description: Conflict
content:
Expand All @@ -39,7 +66,7 @@ components:
example:
errors:
- code: "CONFLICT"
message: "Product Team cannot be deleted as it still has associated Product Ids ['P.123-XYZ', 'P.456-ABC']"
message: "Product Team cannot be deleted as it still has associated Product Ids ['P.1X3-XYZ', 'P.4Y6-ABC']"
BadRequest:
description: Bad request (multiple error types)
content:
Expand Down Expand Up @@ -103,6 +130,33 @@ components:
errors:
- code: "MISSING_VALUE"
message: "CreateProductTeamIncomingParams.ods_code: field required"
CreateProductBadRequest:
description: createProduct Bad request
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
examples:
MissingValue:
value:
errors:
- code: "MISSING_VALUE"
message: "CreateCpmProductIncomingParams.name: field required"
ExtraFieldsValidationError:
value:
errors:
- code: "VALIDATION_ERROR"
message: "CreateCpmProductIncomingParams.extra_name: extra fields not permitted"
EmptyValueValidationError:
value:
errors:
- code: "VALIDATION_ERROR"
message: "CreateCpmProductIncomingParams.name: ensure this value has at least 1 characters"
InvalidJSONValidationError:
value:
errors:
- code: "VALIDATION_ERROR"
message: "Invalid JSON body was provided: line 1 column 20 (char 19)"
headers:
Access-Control-Allow-Origin:
schema:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ components:
name: product_team_id
in: query
required: false
description: The ID of the product team to filter results by.
description: Product Team identifier to filter results by. Either the "internally" generated id (cpm_product_team_id) or the provided team id (product_team_id)
schema:
type: string
OrganisationCodeQuery:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "connecting-party-manager"
version = "2025.03.07"
version = "2025.03.10"
description = "Repository for the Connecting Party Manager API and related services"
authors = ["NHS England"]
license = "LICENSE.md"
Expand Down
4 changes: 4 additions & 0 deletions scripts/UI/ui.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.PHONY: run--ui

run--ui: ## Run the CPM test UI on localhost
npm run --prefix test_ui/product_id_flow dev
9 changes: 7 additions & 2 deletions scripts/infrastructure/apigee/apigee.sh
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ function attach_product(){
_product_name="connecting-party-manager--$_apigee_environment--$API_NAME--app-level0"
_secret_name="$_aws_environment--apigee-app-client-info"
_apigee_stage=$(get_apigee_stage ${_workspace_name})
external_id_secret_name="nhse-cpm--mgmt--${_aws_environment}-external-id"
external_id=$(aws secretsmanager get-secret-value --secret-id $external_id_secret_name --query SecretString --output text)



echo "
Expand All @@ -118,7 +121,7 @@ function attach_product(){
session_name="attach-product-session"
duration_seconds=900

assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --duration-seconds "$duration_seconds")
assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --external-id "$external_id" --duration-seconds "$duration_seconds")
# Check if the assume-role command was successful
if [ $? -eq 0 ]; then

Expand Down Expand Up @@ -183,6 +186,8 @@ function detach_product(){
_product_name="connecting-party-manager--$_apigee_environment--$API_NAME--app-level0"
_secret_name="$_aws_environment--apigee-app-client-info"
_apigee_stage=$(get_apigee_stage ${_workspace_name})
external_id_secret_name="nhse-cpm--mgmt--${_aws_environment}-external-id"
external_id=$(aws secretsmanager get-secret-value --secret-id $external_id_secret_name --query SecretString --output text)


echo "
Expand All @@ -201,7 +206,7 @@ function detach_product(){
session_name="attach-product-session"
duration_seconds=900

assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --duration-seconds "$duration_seconds")
assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --external-id "$external_id" --duration-seconds "$duration_seconds")
# Check if the assume-role command was successful
if [ $? -eq 0 ]; then

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ function _destroy_corrupted_workspace() {
role_arn="arn:aws:iam::${dev_acct}:role/${TERRAFORM_ROLE_NAME}"
session_name="resource-search-session"
duration_seconds=900
assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --duration-seconds "$duration_seconds")
external_id_secret_name="nhse-cpm--mgmt--${ENV}-external-id"
external_id=$(aws secretsmanager get-secret-value --secret-id $external_id_secret_name --query SecretString --output text)

assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --external-id "$external_id" --duration-seconds "$duration_seconds")

# Check if the assume-role command was successful
if [ $? -eq 0 ]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ function _destroy_expired_workspaces() {
role_arn="arn:aws:iam::${dev_acct}:role/NHSDeploymentRole"
session_name="resource-search-session"
duration_seconds=900
assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --duration-seconds "$duration_seconds")

external_id_secret_name="nhse-cpm--mgmt--${ENV}-external-id"
external_id=$(aws secretsmanager get-secret-value --secret-id $external_id_secret_name --query SecretString --output text)

assume_role_output=$(aws sts assume-role --role-arn "$role_arn" --role-session-name "$session_name" --external-id "$external_id" --duration-seconds "$duration_seconds")

# Check if the assume-role command was successful
if [ $? -eq 0 ]; then
Expand Down
Loading
Loading