From fd36993210e2dc4fa6abe4863469e167606327ed Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Thu, 19 Mar 2026 17:54:55 +0000 Subject: [PATCH 01/22] feat: scaffold app with cdk --- .gitignore | 2 + Makefile | 32 + package-lock.json | 1490 ++++++++++++++--- package.json | 1 + packages/cdk/bin/PfPApiApp.ts | 41 + packages/cdk/bin/PfPApiSandboxApp.ts | 11 + packages/cdk/cdk.json | 76 + packages/cdk/nagSuppressions.ts | 51 + packages/cdk/package.json | 23 + packages/cdk/resources/Apis.ts | 65 + packages/cdk/resources/Functions.ts | 138 ++ .../GetMyPrescriptions.ts | 76 + packages/cdk/resources/StateMachines.ts | 58 + packages/cdk/scripts/deleteMainStacks.ts | 11 + packages/cdk/scripts/deletePrStacks.ts | 10 + packages/cdk/stacks/PfPApiSandboxStack.ts | 10 + packages/cdk/stacks/PfPApiStack.ts | 57 + packages/cdk/tsconfig.json | 30 + 18 files changed, 1969 insertions(+), 213 deletions(-) create mode 100644 packages/cdk/bin/PfPApiApp.ts create mode 100644 packages/cdk/bin/PfPApiSandboxApp.ts create mode 100644 packages/cdk/cdk.json create mode 100644 packages/cdk/nagSuppressions.ts create mode 100644 packages/cdk/package.json create mode 100644 packages/cdk/resources/Apis.ts create mode 100644 packages/cdk/resources/Functions.ts create mode 100644 packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts create mode 100644 packages/cdk/resources/StateMachines.ts create mode 100644 packages/cdk/scripts/deleteMainStacks.ts create mode 100644 packages/cdk/scripts/deletePrStacks.ts create mode 100644 packages/cdk/stacks/PfPApiSandboxStack.ts create mode 100644 packages/cdk/stacks/PfPApiStack.ts create mode 100644 packages/cdk/tsconfig.json diff --git a/.gitignore b/.gitignore index 3bf963f19..bb7cf1944 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,10 @@ **/public/ **/coverage/ **/node_modules/ +cdk.out/ .#* __pycache__/ +.env .envrc .idea .vscode/settings.json diff --git a/Makefile b/Makefile index a135cc27f..377ee3337 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,20 @@ +SHELL = /bin/bash +.SHELLFLAGS = -o pipefail -c +stack_name ?= pfp-api +export CDK_APP_NAME=PfPApiApp +export CDK_CONFIG_stackName=${stack_name} +export CDK_CONFIG_versionNumber=undefined +export CDK_CONFIG_commitId=undefined +export CDK_CONFIG_isPullRequest=true # Turns off mTLS and drift detection when true +export CDK_CONFIG_environment=dev +export CDK_CONFIG_logRetentionInDays=30 +export CDK_CONFIG_logLevel=DEBUG +export CDK_CONFIG_targetSpineServer=https://example.org +export CDK_CONFIG_targetServiceSearchServer=example.org +export CDK_CONFIG_toggleGetStatusUpdates=false +export CDK_CONFIG_allowNhsNumberOverride=false +export CDK_CONFIG_forwardCsocLogs=false + .PHONY: install build test publish release clean install-node install-python install-hooks sam-build sam-build-sandbox sam-run-local sam-sync sam-sync-sandbox sam-deploy sam-delete sam-list-endpoints sam-list-resources sam-list-outputs sam-validate sam-validate-sandbox sam-deploy-package compile-node compile compile-specification download-get-secrets-layer lint-node lint test clean deep-clean install: install-python install-hooks install-node @@ -104,6 +121,18 @@ sam-deploy-package: guard-artifact_bucket guard-artifact_bucket_prefix guard-sta EnableAlerts=$$ENABLE_ALERTS \ StateMachineLogLevel=$$STATE_MACHINE_LOG_LEVEL +cdk-deploy: + CDK_CONFIG_stackName=${stack_name} REQUIRE_APPROVAL="$${REQUIRE_APPROVAL:-any-change}" npm run cdk-deploy --workspace packages/cdk + +cdk-synth: download-get-secrets-layer + CDK_CONFIG_stackName=${stack_name} npm run cdk-synth --workspace packages/cdk + +cdk-diff: + CDK_CONFIG_stackName=${stack_name} npm run cdk-diff --workspace packages/cdk + +cdk-watch: + CDK_CONFIG_stackName=${stack_name} REQUIRE_APPROVAL="$${REQUIRE_APPROVAL:-any-change}" npm run cdk-watch --workspace packages/cdk + compile-node: npx tsc --build tsconfig.build.json @@ -128,6 +157,7 @@ download-get-secrets-layer: fi lint-node: compile-node + npm run lint --workspace packages/cdk npm run lint --workspace packages/capabilityStatement npm run lint --workspace packages/getMyPrescriptions npm run lint --workspace packages/enrichPrescriptions @@ -142,6 +172,7 @@ lint: lint-node actionlint shellcheck cfn-lint echo "Linting complete" test: compile + npm run test --workspace packages/cdk npm run test --workspace packages/capabilityStatement npm run test --workspace packages/getMyPrescriptions npm run test --workspace packages/enrichPrescriptions @@ -153,6 +184,7 @@ test: compile npm run test --workspace packages/common/testing clean: + rm -rf packages/cdk/coverage rm -rf packages/capabilityStatement/coverage rm -rf packages/getMyPrescriptions/coverage rm -rf packages/enrichPrescriptions/coverage diff --git a/package-lock.json b/package-lock.json index f815c5448..230fc13c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "MIT", "workspaces": [ + "packages/cdk", "packages/capabilityStatement", "packages/getMyPrescriptions", "packages/enrichPrescriptions", @@ -38,6 +39,132 @@ "vitest": "^4.1.0" } }, + "node_modules/@aws-cdk/asset-awscli-v1": { + "version": "2.2.263", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.263.tgz", + "integrity": "sha512-X9JvcJhYcb7PHs8R7m4zMablO5C9PGb/hYfLnxds9h/rKJu6l7MiXE/SabCibuehxPnuO/vk+sVVJiUWrccarQ==", + "license": "Apache-2.0" + }, + "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.1.tgz", + "integrity": "sha512-We4bmHaowOPHr+IQR4/FyTGjRfjgBj4ICMjtqmJeBDWad3Q/6St12NT07leNtyuukv2qMhtSZJQorD8KpKTwRA==", + "license": "Apache-2.0" + }, + "node_modules/@aws-cdk/cloud-assembly-schema": { + "version": "52.2.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-52.2.0.tgz", + "integrity": "sha512-ourZjixQ/UfsZc7gdk3vt1eHBODMUjQTYYYCY3ZX8fiXyHtWNDAYZPrXUK96jpCC2fLP+tfHTJrBjZ563pmcEw==", + "bundleDependencies": [ + "jsonschema", + "semver" + ], + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "jsonschema": "~1.4.1", + "semver": "^7.7.3" + }, + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { + "version": "1.4.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { + "version": "7.7.3", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/crc32c": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", + "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@aws-crypto/sha256-browser": { "version": "5.2.0", "license": "Apache-2.0", @@ -211,6 +338,175 @@ } } }, + "node_modules/@aws-sdk/client-cloudformation": { + "version": "3.1011.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.1011.0.tgz", + "integrity": "sha512-v7qixZ+o2+t5f+Y+9qN5EyEejdkGpeDxhkRBaW9xOlE41owhsv7y1EmCsW1Lo5W+0krm0r/09w/TWy7rLHa57Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.20", + "@aws-sdk/credential-provider-node": "^3.972.21", + "@aws-sdk/middleware-host-header": "^3.972.8", + "@aws-sdk/middleware-logger": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.8", + "@aws-sdk/middleware-user-agent": "^3.972.21", + "@aws-sdk/region-config-resolver": "^3.972.8", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@aws-sdk/util-user-agent-browser": "^3.972.8", + "@aws-sdk/util-user-agent-node": "^3.973.7", + "@smithy/config-resolver": "^4.4.11", + "@smithy/core": "^3.23.11", + "@smithy/fetch-http-handler": "^5.3.15", + "@smithy/hash-node": "^4.2.12", + "@smithy/invalid-dependency": "^4.2.12", + "@smithy/middleware-content-length": "^4.2.12", + "@smithy/middleware-endpoint": "^4.4.25", + "@smithy/middleware-retry": "^4.4.42", + "@smithy/middleware-serde": "^4.2.14", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/node-http-handler": "^4.4.16", + "@smithy/protocol-http": "^5.3.12", + "@smithy/smithy-client": "^4.12.5", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.41", + "@smithy/util-defaults-mode-node": "^4.2.44", + "@smithy/util-endpoints": "^3.3.3", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-retry": "^4.2.12", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.13", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-route-53": { + "version": "3.1011.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-route-53/-/client-route-53-3.1011.0.tgz", + "integrity": "sha512-niEdBaAuouO9HVhzv9U7yOsqP3qNQd0F7/igVIu9jXV3yf1ljQMeUa1wAPhZ8X/lIEaXce1Yp7+cdwHTfO8IwQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.20", + "@aws-sdk/credential-provider-node": "^3.972.21", + "@aws-sdk/middleware-host-header": "^3.972.8", + "@aws-sdk/middleware-logger": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.8", + "@aws-sdk/middleware-sdk-route53": "^3.972.10", + "@aws-sdk/middleware-user-agent": "^3.972.21", + "@aws-sdk/region-config-resolver": "^3.972.8", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@aws-sdk/util-user-agent-browser": "^3.972.8", + "@aws-sdk/util-user-agent-node": "^3.973.7", + "@smithy/config-resolver": "^4.4.11", + "@smithy/core": "^3.23.11", + "@smithy/fetch-http-handler": "^5.3.15", + "@smithy/hash-node": "^4.2.12", + "@smithy/invalid-dependency": "^4.2.12", + "@smithy/middleware-content-length": "^4.2.12", + "@smithy/middleware-endpoint": "^4.4.25", + "@smithy/middleware-retry": "^4.4.42", + "@smithy/middleware-serde": "^4.2.14", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/node-http-handler": "^4.4.16", + "@smithy/protocol-http": "^5.3.12", + "@smithy/smithy-client": "^4.12.5", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.41", + "@smithy/util-defaults-mode-node": "^4.2.44", + "@smithy/util-endpoints": "^3.3.3", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-retry": "^4.2.12", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.13", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.1011.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1011.0.tgz", + "integrity": "sha512-jY7CGX+vfM/DSi4K8UwaZKoXnhqchmAbKFB1kIuHMfPPqW7l3jC/fUVDb95/njMsB2ymYOTusZEzoCTeUB/4qA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.20", + "@aws-sdk/credential-provider-node": "^3.972.21", + "@aws-sdk/middleware-bucket-endpoint": "^3.972.8", + "@aws-sdk/middleware-expect-continue": "^3.972.8", + "@aws-sdk/middleware-flexible-checksums": "^3.974.0", + "@aws-sdk/middleware-host-header": "^3.972.8", + "@aws-sdk/middleware-location-constraint": "^3.972.8", + "@aws-sdk/middleware-logger": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.8", + "@aws-sdk/middleware-sdk-s3": "^3.972.20", + "@aws-sdk/middleware-ssec": "^3.972.8", + "@aws-sdk/middleware-user-agent": "^3.972.21", + "@aws-sdk/region-config-resolver": "^3.972.8", + "@aws-sdk/signature-v4-multi-region": "^3.996.8", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@aws-sdk/util-user-agent-browser": "^3.972.8", + "@aws-sdk/util-user-agent-node": "^3.973.7", + "@smithy/config-resolver": "^4.4.11", + "@smithy/core": "^3.23.11", + "@smithy/eventstream-serde-browser": "^4.2.12", + "@smithy/eventstream-serde-config-resolver": "^4.3.12", + "@smithy/eventstream-serde-node": "^4.2.12", + "@smithy/fetch-http-handler": "^5.3.15", + "@smithy/hash-blob-browser": "^4.2.13", + "@smithy/hash-node": "^4.2.12", + "@smithy/hash-stream-node": "^4.2.12", + "@smithy/invalid-dependency": "^4.2.12", + "@smithy/md5-js": "^4.2.12", + "@smithy/middleware-content-length": "^4.2.12", + "@smithy/middleware-endpoint": "^4.4.25", + "@smithy/middleware-retry": "^4.4.42", + "@smithy/middleware-serde": "^4.2.14", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/node-http-handler": "^4.4.16", + "@smithy/protocol-http": "^5.3.12", + "@smithy/smithy-client": "^4.12.5", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.41", + "@smithy/util-defaults-mode-node": "^4.2.44", + "@smithy/util-endpoints": "^3.3.3", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-retry": "^4.2.12", + "@smithy/util-stream": "^4.5.19", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.2.13", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/client-secrets-manager": { "version": "3.1016.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.1016.0.tgz", @@ -266,6 +562,7 @@ "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.1016.0.tgz", "integrity": "sha512-9qb58Utss0lJGAcQxftSQ1OY5Dm2aKtn/aBdV2ProFRkyQuxOWJsKMmAAqOpMYnQBEgs6k/ArvBZjQIESrsxfg==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -336,6 +633,19 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/crc64-nvme": { + "version": "3.972.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/crc64-nvme/-/crc64-nvme-3.972.5.tgz", + "integrity": "sha512-2VbTstbjKdT+yKi8m7b3a9CiVac+pL/IY2PHJwsaGkkHmuuqkJZIErPck1h6P3T9ghQMLSdMPyW6Qp7Di5swFg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/credential-provider-env": { "version": "3.972.23", "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.23.tgz", @@ -494,28 +804,32 @@ "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-host-header": { + "node_modules/@aws-sdk/middleware-bucket-endpoint": { "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.8.tgz", - "integrity": "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.972.8.tgz", + "integrity": "sha512-WR525Rr2QJSETa9a050isktyWi/4yIGcmY3BQ1kpHqb0LqUglQHCS8R27dTJxxWNZvQ0RVGtEZjTCbZJpyF3Aw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", + "@smithy/util-config-provider": "^4.2.2", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-logger": { + "node_modules/@aws-sdk/middleware-expect-continue": { "version": "3.972.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.8.tgz", - "integrity": "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.972.8.tgz", + "integrity": "sha512-5DTBTiotEES1e2jOHAq//zyzCjeMB78lEHd35u15qnrid4Nxm7diqIf9fQQ3Ov0ChH1V3Vvt13thOnrACmfGVQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.6", + "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "tslib": "^2.6.2" }, @@ -523,75 +837,196 @@ "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.9", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.9.tgz", - "integrity": "sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==", + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.974.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.0.tgz", + "integrity": "sha512-BmdDjqvnuYaC4SY7ypHLXfCSsGYGUZkjCLSZyUAAYn1YT28vbNMJNDwhlfkvvE+hQHG5RJDlEmYuvBxcB9jX1g==", "license": "Apache-2.0", "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "^3.973.20", + "@aws-sdk/crc64-nvme": "^3.972.5", "@aws-sdk/types": "^3.973.6", - "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-stream": "^4.5.19", + "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.26", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.26.tgz", - "integrity": "sha512-AilFIh4rI/2hKyyGN6XrB0yN96W2o7e7wyrPWCM6QjZM1mcC/pVkW3IWWRvuBWMpVP8Fg+rMpbzeLQ6dTM4gig==", + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.8.tgz", + "integrity": "sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.25", "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@smithy/core": "^3.23.12", "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", - "@smithy/util-retry": "^4.2.12", "tslib": "^2.6.2" }, "engines": { "node": ">=20.0.0" } }, - "node_modules/@aws-sdk/nested-clients": { - "version": "3.996.15", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.15.tgz", - "integrity": "sha512-k6WAVNkub5DrU46iPQvH1m0xc1n+0dX79+i287tYJzf5g1yU2rX3uf4xNeL5JvK1NtYgfwMnsxHqhOXFBn367A==", + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.972.8.tgz", + "integrity": "sha512-KaUoFuoFPziIa98DSQsTPeke1gvGXlc5ZGMhy+b+nLxZ4A7jmJgLzjEF95l8aOQN2T/qlPP3MrAyELm8ExXucw==", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.25", - "@aws-sdk/middleware-host-header": "^3.972.8", - "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.9", - "@aws-sdk/middleware-user-agent": "^3.972.26", - "@aws-sdk/region-config-resolver": "^3.972.10", "@aws-sdk/types": "^3.973.6", - "@aws-sdk/util-endpoints": "^3.996.5", - "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.12", - "@smithy/config-resolver": "^4.4.13", - "@smithy/core": "^3.23.12", - "@smithy/fetch-http-handler": "^5.3.15", - "@smithy/hash-node": "^4.2.12", - "@smithy/invalid-dependency": "^4.2.12", - "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.27", - "@smithy/middleware-retry": "^4.4.44", - "@smithy/middleware-serde": "^4.2.15", - "@smithy/middleware-stack": "^4.2.12", - "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.5.0", - "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", - "@smithy/url-parser": "^4.2.12", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.8.tgz", + "integrity": "sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.9.tgz", + "integrity": "sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-route53": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-route53/-/middleware-sdk-route53-3.972.10.tgz", + "integrity": "sha512-eVSTduHxtUd1M/KxKFiAHj1Q9djzx428iPe7Yd8yJdEsgnVH0wPFsCK/ExB0Rv/yIYlVXdBlFJmMj0FgRj4crQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.972.20", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.20.tgz", + "integrity": "sha512-yhva/xL5H4tWQgsBjwV+RRD0ByCzg0TcByDCLp3GXdn/wlyRNfy8zsswDtCvr1WSKQkSQYlyEzPuWkJG0f5HvQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.20", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/core": "^3.23.11", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/protocol-http": "^5.3.12", + "@smithy/signature-v4": "^5.3.12", + "@smithy/smithy-client": "^4.12.5", + "@smithy/types": "^4.13.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-middleware": "^4.2.12", + "@smithy/util-stream": "^4.5.19", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.972.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.972.8.tgz", + "integrity": "sha512-wqlK0yO/TxEC2UsY9wIlqeeutF6jjLe0f96Pbm40XscTo57nImUk9lBcw0dPgsm0sppFtAkSlDrfpK+pC30Wqw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.6", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.26", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.26.tgz", + "integrity": "sha512-AilFIh4rI/2hKyyGN6XrB0yN96W2o7e7wyrPWCM6QjZM1mcC/pVkW3IWWRvuBWMpVP8Fg+rMpbzeLQ6dTM4gig==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.25", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@smithy/core": "^3.23.12", + "@smithy/protocol-http": "^5.3.12", + "@smithy/types": "^4.13.1", + "@smithy/util-retry": "^4.2.12", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.996.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.15.tgz", + "integrity": "sha512-k6WAVNkub5DrU46iPQvH1m0xc1n+0dX79+i287tYJzf5g1yU2rX3uf4xNeL5JvK1NtYgfwMnsxHqhOXFBn367A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.25", + "@aws-sdk/middleware-host-header": "^3.972.8", + "@aws-sdk/middleware-logger": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.9", + "@aws-sdk/middleware-user-agent": "^3.972.26", + "@aws-sdk/region-config-resolver": "^3.972.10", + "@aws-sdk/types": "^3.973.6", + "@aws-sdk/util-endpoints": "^3.996.5", + "@aws-sdk/util-user-agent-browser": "^3.972.8", + "@aws-sdk/util-user-agent-node": "^3.973.12", + "@smithy/config-resolver": "^4.4.13", + "@smithy/core": "^3.23.12", + "@smithy/fetch-http-handler": "^5.3.15", + "@smithy/hash-node": "^4.2.12", + "@smithy/invalid-dependency": "^4.2.12", + "@smithy/middleware-content-length": "^4.2.12", + "@smithy/middleware-endpoint": "^4.4.27", + "@smithy/middleware-retry": "^4.4.44", + "@smithy/middleware-serde": "^4.2.15", + "@smithy/middleware-stack": "^4.2.12", + "@smithy/node-config-provider": "^4.3.12", + "@smithy/node-http-handler": "^4.5.0", + "@smithy/protocol-http": "^5.3.12", + "@smithy/smithy-client": "^4.12.7", + "@smithy/types": "^4.13.1", + "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", @@ -623,6 +1058,23 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.8.tgz", + "integrity": "sha512-n1qYFD+tbqZuyskVaxUE+t10AUz9g3qzDw3Tp6QZDKmqsjfDmZBd4GIk2EKJJNtcCBtE5YiUjDYA+3djFAFBBg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "^3.972.20", + "@aws-sdk/types": "^3.973.6", + "@smithy/protocol-http": "^5.3.12", + "@smithy/signature-v4": "^5.3.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/token-providers": { "version": "3.1018.0", "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1018.0.tgz", @@ -654,6 +1106,18 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.3.tgz", + "integrity": "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/util-endpoints": { "version": "3.996.5", "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.5.tgz", @@ -1603,6 +2067,21 @@ "uninstall": "^0.0.0" } }, + "node_modules/@nhsdigital/eps-cdk-constructs": { + "version": "1.6.0", + "resolved": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", + "integrity": "sha512-pXQR0pWmBeaRdHoD6pLvbjKvDJnrorqaMiemCqK2TfUWM3B77aj14YdeaUo8lAC6tDfNYAr/zzao+DjT04z5fA==", + "license": "MIT", + "dependencies": { + "@aws-sdk/client-cloudformation": "^3.1008.0", + "@aws-sdk/client-route-53": "^3.1008.0", + "@aws-sdk/client-s3": "^3.1008.0", + "aws-cdk": "^2.1111.0", + "aws-cdk-lib": "^2.243.0", + "cdk-nag": "^2.37.52", + "constructs": "^10.5.1" + } + }, "node_modules/@nhsdigital/eps-spine-client": { "version": "2.1.78", "license": "MIT", @@ -1631,6 +2110,7 @@ "version": "1.9.0", "dev": true, "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -2514,6 +2994,31 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.2.tgz", + "integrity": "sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.3.tgz", + "integrity": "sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/config-resolver": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.13.tgz", @@ -2568,6 +3073,76 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.12.tgz", + "integrity": "sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.13.1", + "@smithy/util-hex-encoding": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.12.tgz", + "integrity": "sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.12.tgz", + "integrity": "sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.12.tgz", + "integrity": "sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.12.tgz", + "integrity": "sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.12", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/fetch-http-handler": { "version": "5.3.15", "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.15.tgz", @@ -2584,6 +3159,21 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/hash-blob-browser": { + "version": "4.2.13", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.13.tgz", + "integrity": "sha512-YrF4zWKh+ghLuquldj6e/RzE3xZYL8wIPfkt0MqCRphVICjyyjH8OwKD7LLlKpVEbk4FLizFfC1+gwK6XQdR3g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/chunked-blob-reader": "^5.2.2", + "@smithy/chunked-blob-reader-native": "^4.2.3", + "@smithy/types": "^4.13.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/hash-node": { "version": "4.2.12", "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.12.tgz", @@ -2599,6 +3189,20 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/hash-stream-node": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.12.tgz", + "integrity": "sha512-O3YbmGExeafuM/kP7Y8r6+1y0hIh3/zn6GROx0uNlB54K9oihAL75Qtc+jFfLNliTi6pxOAYZrRKD9A7iA6UFw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/invalid-dependency": { "version": "4.2.12", "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.12.tgz", @@ -2622,6 +3226,20 @@ "node": ">=18.0.0" } }, + "node_modules/@smithy/md5-js": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.12.tgz", + "integrity": "sha512-W/oIpHCpWU2+iAkfZYyGWE+qkpuf3vEXHLxQQDx9FPNZTTdnul0dZ2d/gUFrtQ5je1G2kp4cjG0/24YueG2LbQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.13.1", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@smithy/middleware-content-length": { "version": "4.2.12", "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.12.tgz", @@ -3172,6 +3790,7 @@ "integrity": "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.18.0" } @@ -3222,6 +3841,7 @@ "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.57.2", "@typescript-eslint/types": "8.57.2", @@ -3492,235 +4112,643 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.1.tgz", - "integrity": "sha512-f7+FPy75vN91QGWsITueq0gedwUZy1fLtHOCMeQpjs8jTekAHeKP80zfDEnhrleviLHzVSDXIWuCIOFn3D3f8A==", - "dev": true, + "node_modules/@vitest/runner": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.1.tgz", + "integrity": "sha512-f7+FPy75vN91QGWsITueq0gedwUZy1fLtHOCMeQpjs8jTekAHeKP80zfDEnhrleviLHzVSDXIWuCIOFn3D3f8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.1", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.1.tgz", + "integrity": "sha512-kMVSgcegWV2FibXEx9p9WIKgje58lcTbXgnJixfcg15iK8nzCXhmalL0ZLtTWLW9PH1+1NEDShiFFedB3tEgWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.1", + "@vitest/utils": "4.1.1", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.1.tgz", + "integrity": "sha512-6Ti/KT5OVaiupdIZEuZN7l3CZcR0cxnxt70Z0//3CtwgObwA6jZhmVBA3yrXSVN3gmwjgd7oDNLlsXz526gpRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.1.tgz", + "integrity": "sha512-cNxAlaB3sHoCdL6pj6yyUXv9Gry1NHNg0kFTXdvSIZXLHsqKH7chiWOkwJ5s5+d/oMwcoG9T0bKU38JZWKusrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.1", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/apim-spec": { + "resolved": "packages/specification", + "link": true + }, + "node_modules/arg": { + "version": "4.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz", + "integrity": "sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/aws-cdk": { + "version": "2.1111.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1111.0.tgz", + "integrity": "sha512-69AVF04cxbAhYzmeJYtUF5bs6ruNnH05EQZJfjadk5Lpg+HVaJY2NjG/2qgsMmKrfRgvLet73Ir8ehVlAaaGng==", + "license": "Apache-2.0", + "bin": { + "cdk": "bin/cdk" + }, + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/aws-cdk-lib": { + "version": "2.243.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.243.0.tgz", + "integrity": "sha512-qIhg/3gSNeZ9LoVmDATO45HPk+POkoCfPZRezeOPhd2kAJ/wzYswyUcMqpDWXrlRrEVYntxsykQs+2eMA04Isg==", + "bundleDependencies": [ + "@balena/dockerignore", + "@aws-cdk/cloud-assembly-api", + "case", + "fs-extra", + "ignore", + "jsonschema", + "minimatch", + "punycode", + "semver", + "table", + "yaml", + "mime-types" + ], + "license": "Apache-2.0", + "dependencies": { + "@aws-cdk/asset-awscli-v1": "2.2.263", + "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.1", + "@aws-cdk/cloud-assembly-api": "^2.1.1", + "@aws-cdk/cloud-assembly-schema": "^52.1.0", + "@balena/dockerignore": "^1.0.2", + "case": "1.6.3", + "fs-extra": "^11.3.3", + "ignore": "^5.3.2", + "jsonschema": "^1.5.0", + "mime-types": "^2.1.35", + "minimatch": "^10.2.3", + "punycode": "^2.3.1", + "semver": "^7.7.4", + "table": "^6.9.0", + "yaml": "1.10.2" + }, + "engines": { + "node": ">= 20.0.0" + }, + "peerDependencies": { + "constructs": "^10.5.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api": { + "version": "2.1.1", + "bundleDependencies": [ + "jsonschema", + "semver" + ], + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "jsonschema": "~1.4.1", + "semver": "^7.7.3" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "@aws-cdk/cloud-assembly-schema": ">=52.1.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api/node_modules/jsonschema": { + "version": "1.4.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api/node_modules/semver": { + "version": "7.7.3", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { + "version": "1.0.2", + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/aws-cdk-lib/node_modules/ajv": { + "version": "8.18.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-regex": { + "version": "5.0.1", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-styles": { + "version": "4.3.0", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/astral-regex": { + "version": "2.0.0", + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/balanced-match": { + "version": "4.0.4", + "inBundle": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/aws-cdk-lib/node_modules/brace-expansion": { + "version": "5.0.3", + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/aws-cdk-lib/node_modules/case": { + "version": "1.6.3", + "inBundle": true, + "license": "(MIT OR GPL-3.0-or-later)", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/color-convert": { + "version": "2.0.1", + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/color-name": { + "version": "1.1.4", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/emoji-regex": { + "version": "8.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { + "version": "3.1.3", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-uri": { + "version": "3.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/aws-cdk-lib/node_modules/fs-extra": { + "version": "11.3.3", + "inBundle": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.1", - "pathe": "^2.0.3" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=14.14" } }, - "node_modules/@vitest/snapshot": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.1.tgz", - "integrity": "sha512-kMVSgcegWV2FibXEx9p9WIKgje58lcTbXgnJixfcg15iK8nzCXhmalL0ZLtTWLW9PH1+1NEDShiFFedB3tEgWg==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/graceful-fs": { + "version": "4.2.11", + "inBundle": true, + "license": "ISC" + }, + "node_modules/aws-cdk-lib/node_modules/ignore": { + "version": "5.3.2", + "inBundle": true, "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "4.1.1", - "@vitest/utils": "4.1.1", - "magic-string": "^0.30.21", - "pathe": "^2.0.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 4" } }, - "node_modules/@vitest/spy": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.1.tgz", - "integrity": "sha512-6Ti/KT5OVaiupdIZEuZN7l3CZcR0cxnxt70Z0//3CtwgObwA6jZhmVBA3yrXSVN3gmwjgd7oDNLlsXz526gpRA==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "inBundle": true, "license": "MIT", - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">=8" } }, - "node_modules/@vitest/utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.1.tgz", - "integrity": "sha512-cNxAlaB3sHoCdL6pj6yyUXv9Gry1NHNg0kFTXdvSIZXLHsqKH7chiWOkwJ5s5+d/oMwcoG9T0bKU38JZWKusrQ==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { + "version": "1.0.0", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/jsonfile": { + "version": "6.2.0", + "inBundle": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.1", - "convert-source-map": "^2.0.0", - "tinyrainbow": "^3.0.3" + "universalify": "^2.0.0" }, - "funding": { - "url": "https://opencollective.com/vitest" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/jsonschema": { + "version": "1.5.0", + "inBundle": true, "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, "engines": { - "node": ">=6.5" + "node": "*" } }, - "node_modules/acorn": { - "version": "8.16.0", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { + "version": "4.4.2", + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/mime-db": { + "version": "1.52.0", + "inBundle": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, "engines": { - "node": ">=0.4.0" + "node": ">= 0.6" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/mime-types": { + "version": "2.1.35", + "inBundle": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "dev": true, - "license": "MIT", + "node_modules/aws-cdk-lib/node_modules/minimatch": { + "version": "10.2.4", + "inBundle": true, + "license": "BlueOak-1.0.0", "dependencies": { - "acorn": "^8.11.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=0.4.0" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/agent-base": { - "version": "7.1.4", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/punycode": { + "version": "2.3.1", + "inBundle": true, "license": "MIT", "engines": { - "node": ">= 14" + "node": ">=6" } }, - "node_modules/ajv": { - "version": "6.14.0", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/require-from-string": { + "version": "2.0.2", + "inBundle": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/semver": { + "version": "7.7.4", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=10" } }, - "node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/slice-ansi": { + "version": "4.0.0", + "inBundle": true, "license": "MIT", "dependencies": { - "ajv": "^8.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, - "peerDependencies": { - "ajv": "^8.0.0" + "engines": { + "node": ">=10" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/string-width": { + "version": "4.2.3", + "inBundle": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=8" } }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, + "node_modules/aws-cdk-lib/node_modules/strip-ansi": { + "version": "6.0.1", + "inBundle": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/apim-spec": { - "resolved": "packages/specification", - "link": true - }, - "node_modules/arg": { - "version": "4.1.3", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" + "node_modules/aws-cdk-lib/node_modules/table": { + "version": "6.9.0", + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } }, - "node_modules/assertion-error": { + "node_modules/aws-cdk-lib/node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, + "inBundle": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 10.0.0" } }, - "node_modules/ast-v8-to-istanbul": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.0.tgz", - "integrity": "sha512-1fSfIwuDICFA4LKkCzRPO7F0hzFf0B7+Xqrl27ynQaa+Rh0e1Es0v6kWHPott3lU10AyAr7oKHa65OppjLn3Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "estree-walker": "^3.0.3", - "js-tokens": "^10.0.0" + "node_modules/aws-cdk-lib/node_modules/yaml": { + "version": "1.10.2", + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">= 6" } }, - "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", - "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "license": "MIT" - }, "node_modules/axios": { "version": "1.13.6", "license": "MIT", + "peer": true, "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", @@ -3814,6 +4842,20 @@ "resolved": "packages/capabilityStatement", "link": true }, + "node_modules/cdk": { + "resolved": "packages/cdk", + "link": true + }, + "node_modules/cdk-nag": { + "version": "2.37.55", + "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.37.55.tgz", + "integrity": "sha512-xcAkygwbph3pp7N0UEzJBmXUH/MIsluV7DYJSeZ/V3yCr0Y0QaRGO298WyD6mi4K+Rmnpl+EJoWUxcOblOqLKA==", + "license": "Apache-2.0", + "peerDependencies": { + "aws-cdk-lib": "^2.176.0", + "constructs": "^10.0.5" + } + }, "node_modules/chai": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", @@ -3951,6 +4993,13 @@ "node": ">= 0.8" } }, + "node_modules/constructs": { + "version": "10.5.1", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.5.1.tgz", + "integrity": "sha512-f/TfFXiS3G/yVIXDjOQn9oTlyu9Wo7Fxyjj7lb8r92iO81jR2uST+9MstxZTmDGx/CgIbxCXkFXgupnLTNxQZg==", + "license": "Apache-2.0", + "peer": true + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -4218,6 +5267,7 @@ "integrity": "sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", @@ -4591,7 +5641,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -4652,7 +5701,6 @@ }, "node_modules/get-tsconfig": { "version": "4.13.0", - "dev": true, "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -5448,6 +6496,7 @@ "version": "6.15.0", "dev": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -5948,6 +6997,7 @@ "version": "19.2.1", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -5956,6 +7006,7 @@ "version": "19.2.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -6089,7 +7140,6 @@ }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -6344,6 +7394,7 @@ "version": "6.3.9", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@emotion/is-prop-valid": "1.4.0", "@emotion/unitless": "0.10.0", @@ -6543,7 +7594,6 @@ }, "node_modules/tsx": { "version": "4.21.0", - "dev": true, "license": "MIT", "dependencies": { "esbuild": "~0.27.0", @@ -6574,6 +7624,7 @@ "version": "5.9.3", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6658,6 +7709,7 @@ "integrity": "sha512-yF+o4POL41rpAzj5KVILUxm1GCjKnELvaqmU9TLLUbMfDzuN0UpUR9uaDs+mCtjPe+uYPksXDRLQGGPvj1cTmA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "4.1.1", "@vitest/mocker": "4.1.1", @@ -6796,6 +7848,7 @@ "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", @@ -7062,6 +8115,17 @@ "@pfp-common/testing": "^1.0.0" } }, + "packages/cdk": { + "version": "0.1.0", + "dependencies": { + "@nhsdigital/eps-cdk-constructs": "file:../../nhsdigital-eps-cdk-constructs-1.6.0.tgz", + "aws-cdk": "^2.1106.0", + "aws-cdk-lib": "^2.239.0", + "cdk-nag": "^2.37.55", + "constructs": "^10.4.5", + "tsx": "^4.21.0" + } + }, "packages/common/testing": { "name": "@pfp-common/testing", "version": "1.0.0", diff --git a/package.json b/package.json index 00e678561..72c99464c 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "author": "NHS Digital", "license": "MIT", "workspaces": [ + "packages/cdk", "packages/capabilityStatement", "packages/getMyPrescriptions", "packages/enrichPrescriptions", diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts new file mode 100644 index 000000000..01283940a --- /dev/null +++ b/packages/cdk/bin/PfPApiApp.ts @@ -0,0 +1,41 @@ +import { + calculateVersionedStackName, + createApp, + getBooleanConfigFromEnvVar, + getConfigFromEnvVar, + getNumberConfigFromEnvVar +} from "@nhsdigital/eps-cdk-constructs" +import {PfPApiStack} from "../stacks/PfPApiStack" + +function main() { + const {app, props} = createApp({ + productName: "Prescriptions for Patients API", + appName: "PfPApiApp", + repoName: "prescriptionsforpatients", + driftDetectionGroup: "pfp-api" + }) + + const pfpApiStack = new PfPApiStack(app, "PfPApiStack", { + ...props, + stackName: calculateVersionedStackName(getConfigFromEnvVar("stackName"), props), + logRetentionInDays: getNumberConfigFromEnvVar("logRetentionInDays"), + logLevel: getConfigFromEnvVar("logLevel"), + targetSpineServer: getConfigFromEnvVar("targetSpineServer"), + targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer"), + toggleGetStatusUpdates: getConfigFromEnvVar("toggleGetStatusUpdates"), + allowNhsNumberOverride: getConfigFromEnvVar("allowNhsNumberOverride"), + mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile"), + // CSOC API GW log destination - do not change + csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", + forwardCsocLogs: getBooleanConfigFromEnvVar("forwardCsocLogs") + }) + + return pfpApiStack +} + +try { + main() +} catch (error) { + console.error(error) + process.exit(1) +} diff --git a/packages/cdk/bin/PfPApiSandboxApp.ts b/packages/cdk/bin/PfPApiSandboxApp.ts new file mode 100644 index 000000000..e3ebe54c4 --- /dev/null +++ b/packages/cdk/bin/PfPApiSandboxApp.ts @@ -0,0 +1,11 @@ +import {createApp} from "@nhsdigital/eps-cdk-constructs" +import {PfPApiSandboxStack} from "../stacks/PfPApiSandboxStack" + +const {app, props} = createApp({ + productName: "Prescriptions for Patients API", + appName: "PfPApiSandboxApp", + repoName: "prescriptionsforpatients", + driftDetectionGroup: "pfp-api" +}) + +new PfPApiSandboxStack(app, "PfPApiSandboxStack", props) diff --git a/packages/cdk/cdk.json b/packages/cdk/cdk.json new file mode 100644 index 000000000..2fc30f768 --- /dev/null +++ b/packages/cdk/cdk.json @@ -0,0 +1,76 @@ +{ + "watch": { + "include": [ + "packages/**" + ], + "exclude": [ + "**/README.md", + "**/cdk*.json", + "**/*.d.ts", + "**/*.js", + "**/tsconfig.json", + "**/package*.json", + "**/yarn.lock", + "**/node_modules", + "**/tests*", + "**/lib", + "**/coverage", + "**/jest.config.ts", + "**/jest.debug.config.ts" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, + "acknowledged-issue-numbers": [34892] + } +} diff --git a/packages/cdk/nagSuppressions.ts b/packages/cdk/nagSuppressions.ts new file mode 100644 index 000000000..b49660edc --- /dev/null +++ b/packages/cdk/nagSuppressions.ts @@ -0,0 +1,51 @@ +/* eslint-disable max-len */ +import {Stack} from "aws-cdk-lib" +import {safeAddNagSuppressionGroup, safeAddNagSuppression} from "@nhsdigital/eps-cdk-constructs" + +export const nagSuppressions = (stack: Stack) => { + safeAddNagSuppressionGroup( + stack, + [ + "/PfPApiStack/Functions/GetMyPrescriptionsLambda/LambdaPutLogsManagedPolicy/Resource", + "/PfPApiStack/Functions/EnrichPrescriptionsLambda/LambdaPutLogsManagedPolicy/Resource", + "/PfPApiStack/Functions/StatusLambda/LambdaPutLogsManagedPolicy/Resource", + "/PfPApiStack/StateMachines/GetMyPrescriptionsStateMachine/StateMachinePutLogsManagedPolicy/Resource" + ], + [ + { + id: "AwsSolutions-IAM5", + reason: "Suppress error for not having wildcards in permissions. This is a fine as we need to have permissions on all log streams under path" + } + ] + ) + + safeAddNagSuppression( + stack, + "/PfPApiStack/Apis/ApiGateway/ApiGateway/Resource", + [ + { + id: "AwsSolutions-APIG2", + reason: "Suppress error for request validation not being enabled. Validation will be handled by the service logic." + } + ] + ) + + safeAddNagSuppressionGroup( + stack, + [ + "/PfPApiStack/Apis/ApiGateway/ApiGateway/Default/Bundle/GET/Resource", + "/PfPApiStack/Apis/ApiGateway/ApiGateway/Default/_status/GET/Resource" + ], + [ + { + id: "AwsSolutions-APIG4", + reason: "Suppress error for not implementing authorization. Token endpoint should not have an authorizer" + }, + { + id: "AwsSolutions-COG4", + reason: "Suppress error for not implementing a Cognito user pool authorizer. Token endpoint should not have an authorizer" + } + ] + ) + +} diff --git a/packages/cdk/package.json b/packages/cdk/package.json new file mode 100644 index 000000000..35fd4d867 --- /dev/null +++ b/packages/cdk/package.json @@ -0,0 +1,23 @@ +{ + "name": "cdk", + "version": "0.1.0", + "scripts": { + "cdk-synth": "cdk synth --output ../../cdk.out --quiet --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\"", + "cdk-diff": "cdk diff --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\"", + "cdk-deploy": "cdk deploy --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\" --all --ci true --require-approval ${REQUIRE_APPROVAL}", + "cdk-watch": "cdk deploy --app \"npm run tsx -- bin/${CDK_APP_NAME}.ts\" --watch --all --ci true --require-approval ${REQUIRE_APPROVAL}", + "delete-main-stacks": "npm run tsx -- scripts/deleteMainStacks.ts", + "delete-old-pr-stacks": "npm run tsx -- scripts/deletePrStacks.ts", + "lint": "eslint --max-warnings 0 --fix --config ../../eslint.config.mjs .", + "test": "vitest run --coverage", + "tsx": "tsx" + }, + "dependencies": { + "@nhsdigital/eps-cdk-constructs": "file:../../nhsdigital-eps-cdk-constructs-1.6.0.tgz", + "aws-cdk": "^2.1106.0", + "aws-cdk-lib": "^2.239.0", + "cdk-nag": "^2.37.55", + "constructs": "^10.4.5", + "tsx": "^4.21.0" + } +} diff --git a/packages/cdk/resources/Apis.ts b/packages/cdk/resources/Apis.ts new file mode 100644 index 000000000..b1ac0caac --- /dev/null +++ b/packages/cdk/resources/Apis.ts @@ -0,0 +1,65 @@ +import {HttpMethod} from "aws-cdk-lib/aws-lambda" +import { + ExpressStateMachine, + LambdaEndpoint, + RestApiGateway, + StateMachineEndpoint, + TypescriptLambdaFunction +} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" + +export interface ApisProps { + readonly stackName: string + readonly logRetentionInDays: number + readonly mutualTlsTrustStoreKey: string | undefined + functions: {[key: string]: TypescriptLambdaFunction} + stateMachines: {[key: string]: ExpressStateMachine} + readonly forwardCsocLogs: boolean + readonly csocApiGatewayDestination: string +} + +export class Apis extends Construct { + apis: {[key: string]: RestApiGateway} + endpoints: {[key: string]: Construct} + + public constructor(scope: Construct, id: string, props: ApisProps){ + super(scope, id) + + const apiGateway = new RestApiGateway(this, "ApiGateway", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + mutualTlsTrustStoreKey: props.mutualTlsTrustStoreKey, + forwardCsocLogs: props.forwardCsocLogs, + csocApiGatewayDestination: props.csocApiGatewayDestination, + executionPolicies: [ + props.stateMachines.getMyPrescriptions.executionPolicy, + props.functions.status.executionPolicy + ] + }) + const rootResource = apiGateway.api.root + + const getMyPrescriptionsEndpoint = new StateMachineEndpoint(this, "GetMyPrescriptionsEndpoint", { + parentResource: rootResource, + resourceName: "Bundle", + method: HttpMethod.GET, + restApiGatewayRole: apiGateway.role, + stateMachine: props.stateMachines.getMyPrescriptions + }) + + const statusEndpoint = new LambdaEndpoint(this, "StatusEndpoint", { + parentResource: rootResource, + resourceName: "_status", + method: HttpMethod.GET, + restApiGatewayRole: apiGateway.role, + lambdaFunction: props.functions.status + }) + + this.apis = { + api: apiGateway + } + this.endpoints = { + getMyPrescriptions: getMyPrescriptionsEndpoint, + status: statusEndpoint + } + } +} diff --git a/packages/cdk/resources/Functions.ts b/packages/cdk/resources/Functions.ts new file mode 100644 index 000000000..c8b2d89f7 --- /dev/null +++ b/packages/cdk/resources/Functions.ts @@ -0,0 +1,138 @@ +import {Aws, Fn, RemovalPolicy} from "aws-cdk-lib" +import {ManagedPolicy, PolicyStatement} from "aws-cdk-lib/aws-iam" +import {Construct} from "constructs" +import {TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" +import {Code, LayerVersion} from "aws-cdk-lib/aws-lambda" +import {join, resolve} from "node:path" + +export interface FunctionsProps { + readonly stackName: string + readonly version: string + readonly commitId: string + readonly deploymentEnvironment: string + readonly targetSpineServer: string + readonly targetServiceSearchServer: string + readonly toggleGetStatusUpdates: string + readonly allowNhsNumberOverride: string + readonly logRetentionInDays: number + readonly logLevel: string +} + +const baseDir = resolve(__dirname, "../../..") + +export class Functions extends Construct { + functions: {[key: string]: TypescriptLambdaFunction} + + public constructor(scope: Construct, id: string, props: FunctionsProps){ + super(scope, id) + + // Imports + const lambdaAccessSecretsPolicy = ManagedPolicy.fromManagedPolicyArn( + this, "lambdaAccessSecretsPolicy", Fn.importValue("account-resources:LambdaAccessSecretsPolicy")) + + const lambdaDecryptSecretsKMSPolicy = ManagedPolicy.fromManagedPolicyArn( + this, "lambdaDecryptSecretsKMSPolicy", Fn.importValue("account-resources:LambdaDecryptSecretsKMSPolicy")) + + const getPfPParametersPolicy = new ManagedPolicy(this, "GetPfPParametersPolicy", { + description: "Read test case SSM parameters", + statements: [ + new PolicyStatement({ + actions: [ + "ssm:GetParameter", + "ssm:GetParameters" + ], + resources: [ + `arn:aws:ssm:${Aws.REGION}:${Aws.ACCOUNT_ID}:parameter/${props.stackName}-TC007NHSNumber`, + `arn:aws:ssm:${Aws.REGION}:${Aws.ACCOUNT_ID}:parameter/${props.stackName}-TC008NHSNumber`, + `arn:aws:ssm:${Aws.REGION}:${Aws.ACCOUNT_ID}:parameter/${props.stackName}-TC009NHSNumber` + ] + }) + ] + }) + + const lambdaDefaultEnvironmentVariables: {[key: string]: string} = { + STACK_NAME: props.stackName, + TargetSpineServer: props.targetSpineServer, + TargetServiceSearchServer: props.targetServiceSearchServer, + SpinePrivateKeyARN: Fn.importValue("account-resources:SpinePrivateKey"), + SpinePublicCertificateARN: Fn.importValue("account-resources:SpinePublicCertificate"), + SpineASIDARN: Fn.importValue("account-resources:SpineASID"), + SpinePartyKeyARN: Fn.importValue("account-resources:SpinePartyKey"), + SpineCAChainARN: Fn.importValue("account-resources:SpineCAChain"), + ServiceSearch3ApiKeyARN: Fn.importValue("pfp-PfP-ServiceSearch-API-Key") + } + + const getSecretsLambdaLayer = new LayerVersion(this, "GetSecretsLambdaLayer", { + description: "get secrets layer", + code: Code.fromAsset(join(baseDir, "packages/getSecretLayer/lib/get-secrets-layer.zip")), + removalPolicy: RemovalPolicy.RETAIN + }) + + // Resources + const getMyPrescriptionsLambda = new TypescriptLambdaFunction(this, "GetMyPrescriptionsLambda", { + functionName: `${props.stackName}-GetMyPrescriptions`, + projectBaseDir: baseDir, + packageBasePath: "packages/getMyPrescriptions", + entryPoint: "src/getMyPrescriptions.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables, + AWS_LAMBDA_EXEC_WRAPPER: "/opt/get-secrets-layer", + DEPLOYMENT_ENVIRONMENT: props.deploymentEnvironment, + GET_STATUS_UPDATES: props.toggleGetStatusUpdates, + ALLOW_NHS_NUMBER_OVERRIDE: props.allowNhsNumberOverride + }, + layers: [getSecretsLambdaLayer], + additionalPolicies: [ + lambdaAccessSecretsPolicy, + lambdaDecryptSecretsKMSPolicy, + getPfPParametersPolicy + ], + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + const enrichPrescriptionsLambda = new TypescriptLambdaFunction(this, "EnrichPrescriptionsLambda", { + functionName: `${props.stackName}-EnrichPrescriptions`, + projectBaseDir: baseDir, + packageBasePath: "packages/enrichPrescriptions", + entryPoint: "src/enrichPrescriptions.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables, + DEPLOYMENT_ENVIRONMENT: props.deploymentEnvironment, + EXPECT_STATUS_UPDATES: props.toggleGetStatusUpdates + }, + additionalPolicies: [ + getPfPParametersPolicy + ], + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + const statusLambda = new TypescriptLambdaFunction(this, "StatusLambda", { + functionName: `${props.stackName}-status`, + projectBaseDir: baseDir, + packageBasePath: "packages/statusLambda", + entryPoint: "src/statusLambda.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables, + AWS_LAMBDA_EXEC_WRAPPER: "/opt/get-secrets-layer" + }, + layers: [getSecretsLambdaLayer], + additionalPolicies: [lambdaAccessSecretsPolicy, lambdaDecryptSecretsKMSPolicy], + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + this.functions = { + getMyPrescriptions: getMyPrescriptionsLambda, + enrichPrescriptions: enrichPrescriptionsLambda, + status: statusLambda + } + } +} diff --git a/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts new file mode 100644 index 000000000..3752c280f --- /dev/null +++ b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts @@ -0,0 +1,76 @@ +import {IFunction} from "aws-cdk-lib/aws-lambda" +import { + Chain, + Choice, + Condition, + IChainable, + Pass, + TaskInput +} from "aws-cdk-lib/aws-stepfunctions" +import {LambdaInvoke} from "aws-cdk-lib/aws-stepfunctions-tasks" +import {CatchAllErrorPass} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" + +export interface DefinitionProps { + readonly getMyPrescriptionsFunction: IFunction + readonly enrichPrescriptionsFunction: IFunction + readonly getStatusUpdatesFunction: IFunction +} + +export class GetMyPrescriptions extends Construct { + public readonly definition: IChainable + + public constructor(scope: Construct, id: string, props: DefinitionProps){ + super(scope, id) + + const catchAllError = new CatchAllErrorPass(this, "Catch All Error") + + const getMyPrescriptions = new LambdaInvoke(this, "Get My Prescriptions", { + lambdaFunction: props.getMyPrescriptionsFunction, + payload: TaskInput.fromJsonPathAt("$") + }) + getMyPrescriptions.addCatch(catchAllError.state) + + const failedGetMyPrescriptions = new Pass(this, "Failed Get My Prescriptions") + + const parseGetMyPrescriptionsBody = new Pass(this, "Parse Get My Prescriptions Body", { + parameters: { + "body.$": "States.StringToJson($.Payload.body)" + }, + outputPath: "$.body" + }) + + const enrichPrescriptions = new LambdaInvoke(this, "Enrich Prescriptions", { + lambdaFunction: props.enrichPrescriptionsFunction, + payload: TaskInput.fromJsonPathAt("$") + }) + enrichPrescriptions.addCatch(catchAllError.state) + + const getStatusUpdates = new LambdaInvoke(this, "Get Status Updates", { + lambdaFunction: props.getStatusUpdatesFunction, + payload: TaskInput.fromJsonPathAt("$.statusUpdateData"), + resultSelector: { + "Payload.$": "$.Payload" + }, + resultPath: "$.StatusUpdates" + }) + getStatusUpdates.addCatch(enrichPrescriptions, { + resultPath: "$.error" + }) + + const checkGetMyPrescriptionsResult = new Choice(this, "Get My Prescriptions Result") + const evaluateToggleGetStatusUpdates = new Choice(this, "Evaluate Toggle Get Status Updates Parameter") + + const getMyPrescriptionsSucceeded = Condition.numberEquals("$.Payload.statusCode", 200) + const getStatusUpdatesEnabled = Condition.booleanEquals("$.getStatusUpdates", true) + + this.definition = Chain + .start(getMyPrescriptions) + .next(checkGetMyPrescriptionsResult + .when(Condition.not(getMyPrescriptionsSucceeded), failedGetMyPrescriptions) + .otherwise(parseGetMyPrescriptionsBody + .next(evaluateToggleGetStatusUpdates + .when(getStatusUpdatesEnabled, getStatusUpdates.next(enrichPrescriptions)) + .otherwise(enrichPrescriptions)))) + } +} diff --git a/packages/cdk/resources/StateMachines.ts b/packages/cdk/resources/StateMachines.ts new file mode 100644 index 000000000..d7a6a18e6 --- /dev/null +++ b/packages/cdk/resources/StateMachines.ts @@ -0,0 +1,58 @@ +import {Fn} from "aws-cdk-lib" +import {ManagedPolicy, PolicyStatement} from "aws-cdk-lib/aws-iam" +import {Function} from "aws-cdk-lib/aws-lambda" +import {ExpressStateMachine, TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" +import {GetMyPrescriptions} from "./StateMachineDefinitions/GetMyPrescriptions" + +export interface StateMachinesProps { + readonly stackName: string + readonly logRetentionInDays: number + functions: {[key: string]: TypescriptLambdaFunction} +} + +export class StateMachines extends Construct { + stateMachines: {[key: string]: ExpressStateMachine} + + public constructor(scope: Construct, id: string, props: StateMachinesProps){ + super(scope, id) + + // Imports + const getStatusUpdates = Function.fromFunctionArn( + this, "GetStatusUpdates", `${Fn.importValue("psu:functions:GetStatusUpdates:FunctionArn")}:$LATEST`) + const callGetStatusUpdatesManagedPolicy = new ManagedPolicy(this, "CallGetStatusUpdatesManagedPolicy", { + description: "call get status updates lambda from get my prescriptions state machine", + statements: [ + new PolicyStatement({ + actions: [ + "lambda:InvokeFunction" + ], + resources: [ + getStatusUpdates.functionArn + ] + }) + ] + }) + + const getMyPrescriptions = new GetMyPrescriptions(this, "GetMyPrescriptionsStateMachineDefinition", { + getMyPrescriptionsFunction: props.functions.getMyPrescriptions.function, + enrichPrescriptionsFunction: props.functions.enrichPrescriptions.function, + getStatusUpdatesFunction: getStatusUpdates + }) + const getMyPrescriptionsStateMachine = new ExpressStateMachine(this, "GetMyPrescriptionsStateMachine", { + stackName: props.stackName, + stateMachineName: `${props.stackName}-GetMyPrescriptions`, + definition: getMyPrescriptions.definition, + logRetentionInDays: props.logRetentionInDays, + additionalPolicies: [ + props.functions.getMyPrescriptions.executionPolicy, + props.functions.enrichPrescriptions.executionPolicy, + callGetStatusUpdatesManagedPolicy + ] + }) + + this.stateMachines = { + getMyPrescriptions: getMyPrescriptionsStateMachine + } + } +} diff --git a/packages/cdk/scripts/deleteMainStacks.ts b/packages/cdk/scripts/deleteMainStacks.ts new file mode 100644 index 000000000..dfb3b28a8 --- /dev/null +++ b/packages/cdk/scripts/deleteMainStacks.ts @@ -0,0 +1,11 @@ +import {deleteUnusedMainStacks, getActiveApiVersions, getConfigFromEnvVar} from "@nhsdigital/eps-cdk-constructs" + +const awsEnvironment = getConfigFromEnvVar("AWS_ENVIRONMENT", "") +deleteUnusedMainStacks( + "pfp-api", + () => getActiveApiVersions("prescriptions-for-patients"), + `${awsEnvironment}.eps.national.nhs.uk.` +).catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/packages/cdk/scripts/deletePrStacks.ts b/packages/cdk/scripts/deletePrStacks.ts new file mode 100644 index 000000000..39977cbda --- /dev/null +++ b/packages/cdk/scripts/deletePrStacks.ts @@ -0,0 +1,10 @@ +import {deleteUnusedPrStacks} from "@nhsdigital/eps-cdk-constructs" + +deleteUnusedPrStacks( + "pfp-api", + "prescriptionsforpatients", + "dev.eps.national.nhs.uk." +).catch((error) => { + console.error(error) + process.exit(1) +}) diff --git a/packages/cdk/stacks/PfPApiSandboxStack.ts b/packages/cdk/stacks/PfPApiSandboxStack.ts new file mode 100644 index 000000000..49d392259 --- /dev/null +++ b/packages/cdk/stacks/PfPApiSandboxStack.ts @@ -0,0 +1,10 @@ +import {Stack, App} from "aws-cdk-lib" +import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" + +export class PfPApiSandboxStack extends Stack { + public constructor(scope: App, id: string, props: StandardStackProps){ + super(scope, id, props) + + // PLACEHOLDER FOR SANDBOX RESOURCES + } +} diff --git a/packages/cdk/stacks/PfPApiStack.ts b/packages/cdk/stacks/PfPApiStack.ts new file mode 100644 index 000000000..b6f5fa364 --- /dev/null +++ b/packages/cdk/stacks/PfPApiStack.ts @@ -0,0 +1,57 @@ +import {App, Stack} from "aws-cdk-lib" +import {nagSuppressions} from "../nagSuppressions" +import {Functions} from "../resources/Functions" +import {StateMachines} from "../resources/StateMachines" +import {Apis} from "../resources/Apis" +import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" + +export interface PfPApiStackProps extends StandardStackProps { + readonly stackName: string + readonly logRetentionInDays: number + readonly logLevel: string + readonly targetSpineServer: string + readonly targetServiceSearchServer: string + readonly toggleGetStatusUpdates: string + readonly allowNhsNumberOverride: string + readonly mutualTlsTrustStoreKey: string | undefined + readonly csocApiGatewayDestination: string + readonly forwardCsocLogs: boolean +} + +export class PfPApiStack extends Stack { + public constructor(scope: App, id: string, props: PfPApiStackProps){ + super(scope, id, props) + + // Resources + const functions = new Functions(this, "Functions", { + stackName: props.stackName, + version: props.version, + commitId: props.commitId, + deploymentEnvironment: props.environment, + targetSpineServer: props.targetSpineServer, + targetServiceSearchServer: props.targetServiceSearchServer, + toggleGetStatusUpdates: props.toggleGetStatusUpdates, + allowNhsNumberOverride: props.allowNhsNumberOverride, + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel + }) + + const stateMachines = new StateMachines(this, "StateMachines", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + functions: functions.functions + }) + + new Apis(this, "Apis", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + mutualTlsTrustStoreKey: props.mutualTlsTrustStoreKey, + functions: functions.functions, + stateMachines: stateMachines.stateMachines, + csocApiGatewayDestination: props.csocApiGatewayDestination, + forwardCsocLogs: props.forwardCsocLogs + }) + + nagSuppressions(this) + } +} diff --git a/packages/cdk/tsconfig.json b/packages/cdk/tsconfig.json new file mode 100644 index 000000000..b24f926cd --- /dev/null +++ b/packages/cdk/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../../tsconfig.defaults.json", + "compilerOptions": { + "module": "commonjs", + "rootDir": ".", + "outDir": "lib", + "allowImportingTsExtensions": true, + "noEmit": true, + "strict": false, + "lib": [ + "es2020" + ], + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": [ + "../../node_modules/@types" + ] + }, + "include": ["resources/**/*", "constructs/**/*", "policies/**/*", "stacks/**/*", "tests/**/*", "scripts/**/*", "nagSuppressions.ts"], + "exclude": ["node_modules", "cdk.out"] +} From 00aaa8bbe68f81ba5906ca799eb19cfe7b06da20 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Fri, 20 Mar 2026 17:01:29 +0000 Subject: [PATCH 02/22] chore: migrate statemachine to JSONata --- .../GetMyPrescriptions.ts | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts index 3752c280f..6195d88aa 100644 --- a/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts +++ b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts @@ -33,11 +33,8 @@ export class GetMyPrescriptions extends Construct { const failedGetMyPrescriptions = new Pass(this, "Failed Get My Prescriptions") - const parseGetMyPrescriptionsBody = new Pass(this, "Parse Get My Prescriptions Body", { - parameters: { - "body.$": "States.StringToJson($.Payload.body)" - }, - outputPath: "$.body" + const parseGetMyPrescriptionsBody = Pass.jsonata(this, "Parse Get My Prescriptions Body", { + outputs: "{% $parse($states.input.Payload.body) %}" }) const enrichPrescriptions = new LambdaInvoke(this, "Enrich Prescriptions", { @@ -46,31 +43,28 @@ export class GetMyPrescriptions extends Construct { }) enrichPrescriptions.addCatch(catchAllError.state) - const getStatusUpdates = new LambdaInvoke(this, "Get Status Updates", { + const getStatusUpdates = LambdaInvoke.jsonata(this, "Get Status Updates", { lambdaFunction: props.getStatusUpdatesFunction, - payload: TaskInput.fromJsonPathAt("$.statusUpdateData"), - resultSelector: { - "Payload.$": "$.Payload" - }, - resultPath: "$.StatusUpdates" + payload: TaskInput.fromText("{% $states.input.statusUpdateData %}"), + outputs: "{% $merge([$states.input, {'StatusUpdates': {'Payload': $states.result.Payload}}]) %}" }) getStatusUpdates.addCatch(enrichPrescriptions, { - resultPath: "$.error" + outputs: "{% $merge([$states.input, {'error': $states.errorOutput}]) %}" }) - const checkGetMyPrescriptionsResult = new Choice(this, "Get My Prescriptions Result") - const evaluateToggleGetStatusUpdates = new Choice(this, "Evaluate Toggle Get Status Updates Parameter") - - const getMyPrescriptionsSucceeded = Condition.numberEquals("$.Payload.statusCode", 200) - const getStatusUpdatesEnabled = Condition.booleanEquals("$.getStatusUpdates", true) + const checkGetMyPrescriptionsResult = Choice.jsonata(this, "Get My Prescriptions Result") + const evaluateToggleGetStatusUpdates = Choice.jsonata(this, "Evaluate Toggle Get Status Updates Parameter") this.definition = Chain .start(getMyPrescriptions) .next(checkGetMyPrescriptionsResult - .when(Condition.not(getMyPrescriptionsSucceeded), failedGetMyPrescriptions) + .when(Condition.jsonata("{% $states.input.Payload.statusCode != 200 %}"), failedGetMyPrescriptions) .otherwise(parseGetMyPrescriptionsBody .next(evaluateToggleGetStatusUpdates - .when(getStatusUpdatesEnabled, getStatusUpdates.next(enrichPrescriptions)) + .when( + Condition.jsonata("{% $states.input.getStatusUpdates = true %}"), + getStatusUpdates.next(enrichPrescriptions) + ) .otherwise(enrichPrescriptions)))) } } From 9f6335f2aaddde6c293237085be30d68dc1d424e Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 11:26:06 +0000 Subject: [PATCH 03/22] chore: further json path -> jsonata --- .../StateMachineDefinitions/GetMyPrescriptions.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts index 6195d88aa..a05953239 100644 --- a/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts +++ b/packages/cdk/resources/StateMachineDefinitions/GetMyPrescriptions.ts @@ -25,9 +25,9 @@ export class GetMyPrescriptions extends Construct { const catchAllError = new CatchAllErrorPass(this, "Catch All Error") - const getMyPrescriptions = new LambdaInvoke(this, "Get My Prescriptions", { + const getMyPrescriptions = LambdaInvoke.jsonata(this, "Get My Prescriptions", { lambdaFunction: props.getMyPrescriptionsFunction, - payload: TaskInput.fromJsonPathAt("$") + payload: TaskInput.fromText("{% $states.input %}") }) getMyPrescriptions.addCatch(catchAllError.state) @@ -37,9 +37,9 @@ export class GetMyPrescriptions extends Construct { outputs: "{% $parse($states.input.Payload.body) %}" }) - const enrichPrescriptions = new LambdaInvoke(this, "Enrich Prescriptions", { + const enrichPrescriptions = LambdaInvoke.jsonata(this, "Enrich Prescriptions", { lambdaFunction: props.enrichPrescriptionsFunction, - payload: TaskInput.fromJsonPathAt("$") + payload: TaskInput.fromText("{% $states.input %}") }) enrichPrescriptions.addCatch(catchAllError.state) From 500749fbd5ac198bb394c6660f73ba8bce07fa8b Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 11:38:46 +0000 Subject: [PATCH 04/22] chore: log and continue if TC params not present --- packages/common/utilities/src/config.ts | 40 +++++++++++++------------ 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/packages/common/utilities/src/config.ts b/packages/common/utilities/src/config.ts index 68daa4c83..168479e79 100644 --- a/packages/common/utilities/src/config.ts +++ b/packages/common/utilities/src/config.ts @@ -1,4 +1,5 @@ import {SSMProvider} from "@aws-lambda-powertools/parameters/ssm" +import {Logger} from "@aws-lambda-powertools/logger" const defaultSsmProvider = new SSMProvider({ clientConfig: {region: process.env.AWS_REGION || "eu-west-2"} @@ -9,40 +10,41 @@ export class PfPConfig { static readonly TC008_NHS_NUMBERS_PARAM = "TC008NHSNumber" static readonly TC009_NHS_NUMBERS_PARAM = "TC009NHSNumber" - private ssmProvider: SSMProvider + private readonly ssmProvider: SSMProvider + private readonly logger: Logger constructor(ssmProvider?: SSMProvider) { + this.logger = new Logger() this.ssmProvider = ssmProvider || defaultSsmProvider } - async isTC007(nhsNumber: string) { - // TC007: test case functionality for supplier testing + async isTestCase(nhsNumber: string, param: string) { const env = process.env["DEPLOYMENT_ENVIRONMENT"] - if (env === "prod") return false - const stackName = process.env.STACK_NAME || "pfp" - const TC007_NHS_NUMBERS = await this.ssmProvider.get(`/${stackName}-${PfPConfig.TC007_NHS_NUMBERS_PARAM}`) - return TC007_NHS_NUMBERS ? TC007_NHS_NUMBERS.includes(nhsNumber) : false + + try { + const stackName = process.env.STACK_NAME || "pfp" + const paramValue = await this.ssmProvider.get(`/${stackName}-${param}`) + return paramValue ? paramValue.includes(nhsNumber) : false + } catch (error) { + this.logger.warn(`Cannot read parameter ${param}, continue with test case disabled:`, {error}) + return false + } + } + + async isTC007(nhsNumber: string) { + // TC007: test case functionality for supplier testing + return this.isTestCase(nhsNumber, PfPConfig.TC007_NHS_NUMBERS_PARAM) } async isTC008(nhsNumber: string) { // AEA-5653, AEA-5853 | TC008: force internal error response for supplier testing - const env = process.env["DEPLOYMENT_ENVIRONMENT"] - - if (env === "prod") return false - const stackName = process.env.STACK_NAME || "pfp" - const TC008_NHS_NUMBERS = await this.ssmProvider.get(`/${stackName}-${PfPConfig.TC008_NHS_NUMBERS_PARAM}`) - return TC008_NHS_NUMBERS ? TC008_NHS_NUMBERS.includes(nhsNumber) : false + return this.isTestCase(nhsNumber, PfPConfig.TC008_NHS_NUMBERS_PARAM) } async isTC009(nhsNumber: string) { // TC009: test case functionality for supplier testing - const env = process.env["DEPLOYMENT_ENVIRONMENT"] - - if (env === "prod") return false - const stackName = process.env.STACK_NAME || "pfp" - const TC009_NHS_NUMBERS = await this.ssmProvider.get(`/${stackName}-${PfPConfig.TC009_NHS_NUMBERS_PARAM}`) - return TC009_NHS_NUMBERS ? TC009_NHS_NUMBERS.includes(nhsNumber) : false + return this.isTestCase(nhsNumber, PfPConfig.TC009_NHS_NUMBERS_PARAM) } } From cac5d12c3b2858a86333e22dc50b96eaff2faa3f Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:07:12 +0000 Subject: [PATCH 05/22] fix: no allow TS imports as still on node module resolution Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- packages/cdk/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cdk/tsconfig.json b/packages/cdk/tsconfig.json index b24f926cd..2b73af77d 100644 --- a/packages/cdk/tsconfig.json +++ b/packages/cdk/tsconfig.json @@ -4,7 +4,6 @@ "module": "commonjs", "rootDir": ".", "outDir": "lib", - "allowImportingTsExtensions": true, "noEmit": true, "strict": false, "lib": [ From f794c59747ac8762f494fdc055c0e5c3ed94b039 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:07:56 +0000 Subject: [PATCH 06/22] fix: typo Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- packages/cdk/cdk.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cdk/cdk.json b/packages/cdk/cdk.json index 2fc30f768..4ff6fefe1 100644 --- a/packages/cdk/cdk.json +++ b/packages/cdk/cdk.json @@ -40,7 +40,7 @@ "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, - "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/aws-route53-patterns:useCertificate": true, "@aws-cdk/customresources:installLatestAwsSdkDefault": false, "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, From b9d472ae9acb943ef87901c1ca81c6a7d522e60e Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:14:41 +0000 Subject: [PATCH 07/22] fix: make dependencies Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 377ee3337..e5a0f2557 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,7 @@ sam-deploy-package: guard-artifact_bucket guard-artifact_bucket_prefix guard-sta EnableAlerts=$$ENABLE_ALERTS \ StateMachineLogLevel=$$STATE_MACHINE_LOG_LEVEL -cdk-deploy: +cdk-deploy: download-get-secrets-layer CDK_CONFIG_stackName=${stack_name} REQUIRE_APPROVAL="$${REQUIRE_APPROVAL:-any-change}" npm run cdk-deploy --workspace packages/cdk cdk-synth: download-get-secrets-layer @@ -130,7 +130,7 @@ cdk-synth: download-get-secrets-layer cdk-diff: CDK_CONFIG_stackName=${stack_name} npm run cdk-diff --workspace packages/cdk -cdk-watch: +cdk-watch: download-get-secrets-layer CDK_CONFIG_stackName=${stack_name} REQUIRE_APPROVAL="$${REQUIRE_APPROVAL:-any-change}" npm run cdk-watch --workspace packages/cdk compile-node: From 05c4121911df8cd28567440776d088e12954d710 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 12:52:09 +0000 Subject: [PATCH 08/22] test: minimal fail-fast cdk synth test --- packages/cdk/tests/synth.test.ts | 58 ++++++++++++++++++++++++++++++++ packages/cdk/vitest.config.ts | 5 +++ 2 files changed, 63 insertions(+) create mode 100644 packages/cdk/tests/synth.test.ts create mode 100644 packages/cdk/vitest.config.ts diff --git a/packages/cdk/tests/synth.test.ts b/packages/cdk/tests/synth.test.ts new file mode 100644 index 000000000..0ab4de83c --- /dev/null +++ b/packages/cdk/tests/synth.test.ts @@ -0,0 +1,58 @@ +import {execFileSync} from "node:child_process" +import {resolve} from "node:path" +import {describe, expect, it} from "vitest" + +const cdkPackageRoot = resolve(__dirname, "..") + +function createBaseEnv(): NodeJS.ProcessEnv { + return { + ...process.env, + CI: "true", + CDK_DEFAULT_REGION: "eu-west-2", + CDK_CONFIG_versionNumber: "0.0.0-test", + CDK_CONFIG_commitId: "test-commit", + CDK_CONFIG_isPullRequest: "true", + CDK_CONFIG_environment: "test" + } +} + +describe("CDK synth smoke tests", () => { + it("type-checks the cdk package", () => { + expect(() => { + execFileSync("npx", ["tsc", "-p", "tsconfig.json", "--noEmit"], { + cwd: cdkPackageRoot, + stdio: "pipe" + }) + }).not.toThrow() + }) + + it("synthesizes the sandbox app", () => { + expect(() => { + execFileSync("npx", ["tsx", "bin/PfPApiSandboxApp.ts"], { + cwd: cdkPackageRoot, + stdio: "pipe", + env: createBaseEnv() + }) + }).not.toThrow() + }) + + it("synthesizes the main app", () => { + expect(() => { + execFileSync("npx", ["tsx", "bin/PfPApiApp.ts"], { + cwd: cdkPackageRoot, + stdio: "pipe", + env: { + ...createBaseEnv(), + CDK_CONFIG_stackName: "pfp-test-stack", + CDK_CONFIG_logRetentionInDays: "7", + CDK_CONFIG_logLevel: "INFO", + CDK_CONFIG_targetSpineServer: "https://example-spine.test", + CDK_CONFIG_targetServiceSearchServer: "https://live/service-search-api/", + CDK_CONFIG_toggleGetStatusUpdates: "true", + CDK_CONFIG_allowNhsNumberOverride: "false", + CDK_CONFIG_forwardCsocLogs: "false" + } + }) + }).not.toThrow() + }) +}) diff --git a/packages/cdk/vitest.config.ts b/packages/cdk/vitest.config.ts new file mode 100644 index 000000000..739bbad20 --- /dev/null +++ b/packages/cdk/vitest.config.ts @@ -0,0 +1,5 @@ +import {createVitestConfig} from "../../vitest.default.config" + +export default createVitestConfig({ + workspaceRoot: "../../" +}) From 2db51941f3717f078c2bd920dbde208e3a81d9a7 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 15:06:14 +0000 Subject: [PATCH 09/22] docs: example .env file --- template.env | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 template.env diff --git a/template.env b/template.env new file mode 100644 index 000000000..96b9c5c56 --- /dev/null +++ b/template.env @@ -0,0 +1,5 @@ +export AWS_DEFAULT_PROFILE=Admin-591291862413 +export PATH="$PWD/node_modules/.bin:$PATH" +export stack_name= +export TARGET_SPINE_SERVER=msg.veit07.devspineservices.nhs.uk +export TARGET_SERVICE_SEARCH_SERVER=int.api.service.nhs.uk From ebdbb2b7f510517fb814a66ba3652336ed6d14c3 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 24 Mar 2026 18:50:43 +0000 Subject: [PATCH 10/22] fix: non-prod spine and ss hosts --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e5a0f2557..8b627b594 100644 --- a/Makefile +++ b/Makefile @@ -9,8 +9,8 @@ export CDK_CONFIG_isPullRequest=true # Turns off mTLS and drift detection when t export CDK_CONFIG_environment=dev export CDK_CONFIG_logRetentionInDays=30 export CDK_CONFIG_logLevel=DEBUG -export CDK_CONFIG_targetSpineServer=https://example.org -export CDK_CONFIG_targetServiceSearchServer=example.org +export CDK_CONFIG_targetSpineServer=msg.veit07.devspineservices.nhs.uk +export CDK_CONFIG_targetServiceSearchServer=int.api.service.nhs.uk export CDK_CONFIG_toggleGetStatusUpdates=false export CDK_CONFIG_allowNhsNumberOverride=false export CDK_CONFIG_forwardCsocLogs=false From f11308e7eb1a1a745d6ed49aea4bee9d66830cca Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:00:26 +0000 Subject: [PATCH 11/22] chore: npm audit fix --- package-lock.json | 204 ++++++++++++++++++++++++---------------------- 1 file changed, 107 insertions(+), 97 deletions(-) diff --git a/package-lock.json b/package-lock.json index 230fc13c2..efa4750da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -339,45 +339,45 @@ } }, "node_modules/@aws-sdk/client-cloudformation": { - "version": "3.1011.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.1011.0.tgz", - "integrity": "sha512-v7qixZ+o2+t5f+Y+9qN5EyEejdkGpeDxhkRBaW9xOlE41owhsv7y1EmCsW1Lo5W+0krm0r/09w/TWy7rLHa57Q==", + "version": "3.1018.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudformation/-/client-cloudformation-3.1018.0.tgz", + "integrity": "sha512-wgxqZIWMcblUHnE7lAxHHQr9RGbG756M/7gBrRD2O9Iad2xWC8QhGAmtOO1eD01YeQInJp02ouAiq5BTqNipIg==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.20", - "@aws-sdk/credential-provider-node": "^3.972.21", + "@aws-sdk/core": "^3.973.25", + "@aws-sdk/credential-provider-node": "^3.972.26", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.8", - "@aws-sdk/middleware-user-agent": "^3.972.21", - "@aws-sdk/region-config-resolver": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.9", + "@aws-sdk/middleware-user-agent": "^3.972.26", + "@aws-sdk/region-config-resolver": "^3.972.10", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.7", - "@smithy/config-resolver": "^4.4.11", - "@smithy/core": "^3.23.11", + "@aws-sdk/util-user-agent-node": "^3.973.12", + "@smithy/config-resolver": "^4.4.13", + "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.25", - "@smithy/middleware-retry": "^4.4.42", - "@smithy/middleware-serde": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.27", + "@smithy/middleware-retry": "^4.4.44", + "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.4.16", + "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.5", + "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.41", - "@smithy/util-defaults-mode-node": "^4.2.44", + "@smithy/util-defaults-mode-browser": "^4.3.43", + "@smithy/util-defaults-mode-node": "^4.2.47", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", @@ -390,46 +390,46 @@ } }, "node_modules/@aws-sdk/client-route-53": { - "version": "3.1011.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-route-53/-/client-route-53-3.1011.0.tgz", - "integrity": "sha512-niEdBaAuouO9HVhzv9U7yOsqP3qNQd0F7/igVIu9jXV3yf1ljQMeUa1wAPhZ8X/lIEaXce1Yp7+cdwHTfO8IwQ==", + "version": "3.1018.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-route-53/-/client-route-53-3.1018.0.tgz", + "integrity": "sha512-ZVMWxgkfe50RqYtiPnPIRiKWDytcVft+LB+4a/N7nsd6WY8zhhM06h7ExfLuUtNioMIngaz0OaRuUTb+OcLpZw==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.20", - "@aws-sdk/credential-provider-node": "^3.972.21", + "@aws-sdk/core": "^3.973.25", + "@aws-sdk/credential-provider-node": "^3.972.26", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.8", + "@aws-sdk/middleware-recursion-detection": "^3.972.9", "@aws-sdk/middleware-sdk-route53": "^3.972.10", - "@aws-sdk/middleware-user-agent": "^3.972.21", - "@aws-sdk/region-config-resolver": "^3.972.8", + "@aws-sdk/middleware-user-agent": "^3.972.26", + "@aws-sdk/region-config-resolver": "^3.972.10", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.7", - "@smithy/config-resolver": "^4.4.11", - "@smithy/core": "^3.23.11", + "@aws-sdk/util-user-agent-node": "^3.973.12", + "@smithy/config-resolver": "^4.4.13", + "@smithy/core": "^3.23.12", "@smithy/fetch-http-handler": "^5.3.15", "@smithy/hash-node": "^4.2.12", "@smithy/invalid-dependency": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.25", - "@smithy/middleware-retry": "^4.4.42", - "@smithy/middleware-serde": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.27", + "@smithy/middleware-retry": "^4.4.44", + "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.4.16", + "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.5", + "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.41", - "@smithy/util-defaults-mode-node": "^4.2.44", + "@smithy/util-defaults-mode-browser": "^4.3.43", + "@smithy/util-defaults-mode-node": "^4.2.47", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", @@ -442,34 +442,34 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.1011.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1011.0.tgz", - "integrity": "sha512-jY7CGX+vfM/DSi4K8UwaZKoXnhqchmAbKFB1kIuHMfPPqW7l3jC/fUVDb95/njMsB2ymYOTusZEzoCTeUB/4qA==", + "version": "3.1018.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1018.0.tgz", + "integrity": "sha512-BiGKMjrkAJkyse1ECpVyxVYugf82FB3cM9zgKpx3boFuWobyolG5ri6XjoMIY8fpHddaO8ZClXEedACyelSLWA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.20", - "@aws-sdk/credential-provider-node": "^3.972.21", + "@aws-sdk/core": "^3.973.25", + "@aws-sdk/credential-provider-node": "^3.972.26", "@aws-sdk/middleware-bucket-endpoint": "^3.972.8", "@aws-sdk/middleware-expect-continue": "^3.972.8", - "@aws-sdk/middleware-flexible-checksums": "^3.974.0", + "@aws-sdk/middleware-flexible-checksums": "^3.974.5", "@aws-sdk/middleware-host-header": "^3.972.8", "@aws-sdk/middleware-location-constraint": "^3.972.8", "@aws-sdk/middleware-logger": "^3.972.8", - "@aws-sdk/middleware-recursion-detection": "^3.972.8", - "@aws-sdk/middleware-sdk-s3": "^3.972.20", + "@aws-sdk/middleware-recursion-detection": "^3.972.9", + "@aws-sdk/middleware-sdk-s3": "^3.972.26", "@aws-sdk/middleware-ssec": "^3.972.8", - "@aws-sdk/middleware-user-agent": "^3.972.21", - "@aws-sdk/region-config-resolver": "^3.972.8", - "@aws-sdk/signature-v4-multi-region": "^3.996.8", + "@aws-sdk/middleware-user-agent": "^3.972.26", + "@aws-sdk/region-config-resolver": "^3.972.10", + "@aws-sdk/signature-v4-multi-region": "^3.996.14", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-endpoints": "^3.996.5", "@aws-sdk/util-user-agent-browser": "^3.972.8", - "@aws-sdk/util-user-agent-node": "^3.973.7", - "@smithy/config-resolver": "^4.4.11", - "@smithy/core": "^3.23.11", + "@aws-sdk/util-user-agent-node": "^3.973.12", + "@smithy/config-resolver": "^4.4.13", + "@smithy/core": "^3.23.12", "@smithy/eventstream-serde-browser": "^4.2.12", "@smithy/eventstream-serde-config-resolver": "^4.3.12", "@smithy/eventstream-serde-node": "^4.2.12", @@ -480,25 +480,25 @@ "@smithy/invalid-dependency": "^4.2.12", "@smithy/md5-js": "^4.2.12", "@smithy/middleware-content-length": "^4.2.12", - "@smithy/middleware-endpoint": "^4.4.25", - "@smithy/middleware-retry": "^4.4.42", - "@smithy/middleware-serde": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.27", + "@smithy/middleware-retry": "^4.4.44", + "@smithy/middleware-serde": "^4.2.15", "@smithy/middleware-stack": "^4.2.12", "@smithy/node-config-provider": "^4.3.12", - "@smithy/node-http-handler": "^4.4.16", + "@smithy/node-http-handler": "^4.5.0", "@smithy/protocol-http": "^5.3.12", - "@smithy/smithy-client": "^4.12.5", + "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/url-parser": "^4.2.12", "@smithy/util-base64": "^4.3.2", "@smithy/util-body-length-browser": "^4.2.2", "@smithy/util-body-length-node": "^4.2.3", - "@smithy/util-defaults-mode-browser": "^4.3.41", - "@smithy/util-defaults-mode-node": "^4.2.44", + "@smithy/util-defaults-mode-browser": "^4.3.43", + "@smithy/util-defaults-mode-node": "^4.2.47", "@smithy/util-endpoints": "^3.3.3", "@smithy/util-middleware": "^4.2.12", "@smithy/util-retry": "^4.2.12", - "@smithy/util-stream": "^4.5.19", + "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "@smithy/util-waiter": "^4.2.13", "tslib": "^2.6.2" @@ -838,15 +838,15 @@ } }, "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.974.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.0.tgz", - "integrity": "sha512-BmdDjqvnuYaC4SY7ypHLXfCSsGYGUZkjCLSZyUAAYn1YT28vbNMJNDwhlfkvvE+hQHG5RJDlEmYuvBxcB9jX1g==", + "version": "3.974.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.5.tgz", + "integrity": "sha512-SPSvF0G1t8m8CcB0L+ClNFszzQOvXaxmRj25oRWDf6aU+TuN2PXPFAJ9A6lt1IvX4oGAqqbTdMPTYs/SSHUYYQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "^3.973.20", + "@aws-sdk/core": "^3.973.25", "@aws-sdk/crc64-nvme": "^3.972.5", "@aws-sdk/types": "^3.973.6", "@smithy/is-array-buffer": "^4.2.2", @@ -854,7 +854,7 @@ "@smithy/protocol-http": "^5.3.12", "@smithy/types": "^4.13.1", "@smithy/util-middleware": "^4.2.12", - "@smithy/util-stream": "^4.5.19", + "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -936,23 +936,23 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.972.20", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.20.tgz", - "integrity": "sha512-yhva/xL5H4tWQgsBjwV+RRD0ByCzg0TcByDCLp3GXdn/wlyRNfy8zsswDtCvr1WSKQkSQYlyEzPuWkJG0f5HvQ==", + "version": "3.972.26", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.26.tgz", + "integrity": "sha512-5q7UGSTtt7/KF0Os8wj2VZtlLxeWJVb0e2eDrDJlWot2EIxUNKDDMPFq/FowUqrwZ40rO2bu6BypxaKNvQhI+g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.20", + "@aws-sdk/core": "^3.973.25", "@aws-sdk/types": "^3.973.6", "@aws-sdk/util-arn-parser": "^3.972.3", - "@smithy/core": "^3.23.11", + "@smithy/core": "^3.23.12", "@smithy/node-config-provider": "^4.3.12", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", - "@smithy/smithy-client": "^4.12.5", + "@smithy/smithy-client": "^4.12.7", "@smithy/types": "^4.13.1", "@smithy/util-config-provider": "^4.2.2", "@smithy/util-middleware": "^4.2.12", - "@smithy/util-stream": "^4.5.19", + "@smithy/util-stream": "^4.5.20", "@smithy/util-utf8": "^4.2.2", "tslib": "^2.6.2" }, @@ -1059,12 +1059,12 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.996.8", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.8.tgz", - "integrity": "sha512-n1qYFD+tbqZuyskVaxUE+t10AUz9g3qzDw3Tp6QZDKmqsjfDmZBd4GIk2EKJJNtcCBtE5YiUjDYA+3djFAFBBg==", + "version": "3.996.14", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.14.tgz", + "integrity": "sha512-4nZSrBr1NO+48HCM/6BRU8mnRjuHZjcpziCvLXZk5QVftwWz5Mxqbhwdz4xf7WW88buaTB8uRO2MHklSX1m0vg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "^3.972.20", + "@aws-sdk/middleware-sdk-s3": "^3.972.26", "@aws-sdk/types": "^3.973.6", "@smithy/protocol-http": "^5.3.12", "@smithy/signature-v4": "^5.3.12", @@ -2070,16 +2070,16 @@ "node_modules/@nhsdigital/eps-cdk-constructs": { "version": "1.6.0", "resolved": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", - "integrity": "sha512-pXQR0pWmBeaRdHoD6pLvbjKvDJnrorqaMiemCqK2TfUWM3B77aj14YdeaUo8lAC6tDfNYAr/zzao+DjT04z5fA==", + "integrity": "sha512-AvxfXMhAOcTYafeRwcsZWbSlS8HxsG2ehU6TOjk7z1afquAfxXSECVOJt0iJyF6K1ZqhQm0AeB/gUOIUWfqgbA==", "license": "MIT", "dependencies": { - "@aws-sdk/client-cloudformation": "^3.1008.0", - "@aws-sdk/client-route-53": "^3.1008.0", - "@aws-sdk/client-s3": "^3.1008.0", - "aws-cdk": "^2.1111.0", - "aws-cdk-lib": "^2.243.0", + "@aws-sdk/client-cloudformation": "^3.1018.0", + "@aws-sdk/client-route-53": "^3.1018.0", + "@aws-sdk/client-s3": "^3.1018.0", + "aws-cdk": "^2.1114.1", + "aws-cdk-lib": "^2.244.0", "cdk-nag": "^2.37.52", - "constructs": "^10.5.1" + "constructs": "^10.6.0" } }, "node_modules/@nhsdigital/eps-spine-client": { @@ -4341,9 +4341,9 @@ "license": "MIT" }, "node_modules/aws-cdk": { - "version": "2.1111.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1111.0.tgz", - "integrity": "sha512-69AVF04cxbAhYzmeJYtUF5bs6ruNnH05EQZJfjadk5Lpg+HVaJY2NjG/2qgsMmKrfRgvLet73Ir8ehVlAaaGng==", + "version": "2.1114.1", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1114.1.tgz", + "integrity": "sha512-jMaKPWQQs1G6AbhfCQG2zGrgAhTxzP0jn4T2CuwONuvcV374dMPhfC/LBAv48ruSOgpCK9x6V1xeO/aH3EchAA==", "license": "Apache-2.0", "bin": { "cdk": "bin/cdk" @@ -4353,9 +4353,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.243.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.243.0.tgz", - "integrity": "sha512-qIhg/3gSNeZ9LoVmDATO45HPk+POkoCfPZRezeOPhd2kAJ/wzYswyUcMqpDWXrlRrEVYntxsykQs+2eMA04Isg==", + "version": "2.244.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.244.0.tgz", + "integrity": "sha512-j5FVeZv5W+v6j6OnW8RjoN04T+8pYvDJJV7yXhhj4IiGDKPgMH3fflQLQXJousd2QQk+nSAjghDVJcrZ4GFyGA==", "bundleDependencies": [ "@balena/dockerignore", "@aws-cdk/cloud-assembly-api", @@ -4807,7 +4807,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.2", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", "dev": true, "license": "MIT", "dependencies": { @@ -4994,9 +4996,9 @@ } }, "node_modules/constructs": { - "version": "10.5.1", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.5.1.tgz", - "integrity": "sha512-f/TfFXiS3G/yVIXDjOQn9oTlyu9Wo7Fxyjj7lb8r92iO81jR2uST+9MstxZTmDGx/CgIbxCXkFXgupnLTNxQZg==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.6.0.tgz", + "integrity": "sha512-TxHOnBO5zMo/G76ykzGF/wMpEHu257TbWiIxP9K0Yv/+t70UzgBQiTqjkAsWOPC6jW91DzJI0+ehQV6xDRNBuQ==", "license": "Apache-2.0", "peer": true }, @@ -5110,7 +5112,9 @@ } }, "node_modules/diff": { - "version": "4.0.2", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -5118,7 +5122,9 @@ } }, "node_modules/dompurify": { - "version": "3.3.1", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.3.tgz", + "integrity": "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==", "dev": true, "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { @@ -5746,7 +5752,9 @@ } }, "node_modules/handlebars": { - "version": "4.7.8", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6464,9 +6472,9 @@ } }, "node_modules/minimatch/node_modules/brace-expansion": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", - "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7622,6 +7630,8 @@ }, "node_modules/typescript": { "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "peer": true, From 0f407d809676be04c091731bfcbcbb6a3c2f793e Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Mon, 30 Mar 2026 11:54:19 +0000 Subject: [PATCH 12/22] chore: test latest eps-cdk-utils --- package-lock.json | 37 ++++++++++++++++++------------------- package.json | 1 + 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/package-lock.json b/package-lock.json index efa4750da..d4575caa8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "packages/specification" ], "dependencies": { + "@nhsdigital/eps-cdk-constructs": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", "esbuild": "^0.27.4" }, "devDependencies": { @@ -52,9 +53,9 @@ "license": "Apache-2.0" }, "node_modules/@aws-cdk/cloud-assembly-schema": { - "version": "52.2.0", - "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-52.2.0.tgz", - "integrity": "sha512-ourZjixQ/UfsZc7gdk3vt1eHBODMUjQTYYYCY3ZX8fiXyHtWNDAYZPrXUK96jpCC2fLP+tfHTJrBjZ563pmcEw==", + "version": "53.9.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-53.9.0.tgz", + "integrity": "sha512-Ss7Af943iyyTABqeJS30LylmELpdpGgHzQP87KxO+HGPFIFDsoZymSuU1H5eQAcuuOvcfIPSKA62/lf274UB2A==", "bundleDependencies": [ "jsonschema", "semver" @@ -63,7 +64,7 @@ "peer": true, "dependencies": { "jsonschema": "~1.4.1", - "semver": "^7.7.3" + "semver": "^7.7.4" }, "engines": { "node": ">= 18.0.0" @@ -78,7 +79,7 @@ } }, "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { - "version": "7.7.3", + "version": "7.7.4", "inBundle": true, "license": "ISC", "bin": { @@ -2070,7 +2071,7 @@ "node_modules/@nhsdigital/eps-cdk-constructs": { "version": "1.6.0", "resolved": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", - "integrity": "sha512-AvxfXMhAOcTYafeRwcsZWbSlS8HxsG2ehU6TOjk7z1afquAfxXSECVOJt0iJyF6K1ZqhQm0AeB/gUOIUWfqgbA==", + "integrity": "sha512-pvgW6Wp17YS04fXeFDldma91V/Uc8xdGZDRSg08//tBQ5O+TxYSJ3E+pF0q6bu2wyuG0QqCMD703BLjbATMi8g==", "license": "MIT", "dependencies": { "@aws-sdk/client-cloudformation": "^3.1018.0", @@ -4353,9 +4354,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.244.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.244.0.tgz", - "integrity": "sha512-j5FVeZv5W+v6j6OnW8RjoN04T+8pYvDJJV7yXhhj4IiGDKPgMH3fflQLQXJousd2QQk+nSAjghDVJcrZ4GFyGA==", + "version": "2.245.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.245.0.tgz", + "integrity": "sha512-Yfeb+wKC6s+Ttm/N93C6vY6ksyCh68WaG/j3N6dalJWTW/V4o6hUolHm+v2c2IofJEUS45c5AF/EEj24e9hfMA==", "bundleDependencies": [ "@balena/dockerignore", "@aws-cdk/cloud-assembly-api", @@ -4374,8 +4375,8 @@ "dependencies": { "@aws-cdk/asset-awscli-v1": "2.2.263", "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.1", - "@aws-cdk/cloud-assembly-api": "^2.1.1", - "@aws-cdk/cloud-assembly-schema": "^52.1.0", + "@aws-cdk/cloud-assembly-api": "^2.2.0", + "@aws-cdk/cloud-assembly-schema": "^53.0.0", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", "fs-extra": "^11.3.3", @@ -4386,7 +4387,7 @@ "punycode": "^2.3.1", "semver": "^7.7.4", "table": "^6.9.0", - "yaml": "1.10.2" + "yaml": "1.10.3" }, "engines": { "node": ">= 20.0.0" @@ -4396,7 +4397,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api": { - "version": "2.1.1", + "version": "2.2.0", "bundleDependencies": [ "jsonschema", "semver" @@ -4405,13 +4406,13 @@ "license": "Apache-2.0", "dependencies": { "jsonschema": "~1.4.1", - "semver": "^7.7.3" + "semver": "^7.7.4" }, "engines": { "node": ">= 18.0.0" }, "peerDependencies": { - "@aws-cdk/cloud-assembly-schema": ">=52.1.0" + "@aws-cdk/cloud-assembly-schema": ">=53.0.0" } }, "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api/node_modules/jsonschema": { @@ -4423,7 +4424,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/@aws-cdk/cloud-assembly-api/node_modules/semver": { - "version": "7.7.3", + "version": "7.7.4", "inBundle": true, "license": "ISC", "bin": { @@ -4738,7 +4739,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/yaml": { - "version": "1.10.2", + "version": "1.10.3", "inBundle": true, "license": "ISC", "engines": { @@ -7213,7 +7214,6 @@ }, "node_modules/semver": { "version": "7.7.3", - "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8019,7 +8019,6 @@ }, "node_modules/yaml": { "version": "1.10.2", - "dev": true, "license": "ISC", "engines": { "node": ">= 6" diff --git a/package.json b/package.json index 72c99464c..6f4f472e8 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "vitest": "^4.1.0" }, "dependencies": { + "@nhsdigital/eps-cdk-constructs": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", "esbuild": "^0.27.4" } } From c1c96138dd451eec3355f31320ba7c314deaf4b3 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:18:28 +0000 Subject: [PATCH 13/22] feat: adopt cdk parameters construct --- package-lock.json | 4 ++- packages/cdk/bin/PfPApiApp.ts | 3 +++ packages/cdk/resources/Functions.ts | 41 +++++++++-------------------- packages/cdk/stacks/PfPApiStack.ts | 12 +++++++++ packages/cdk/tests/synth.test.ts | 3 +++ 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4575caa8..0cc213e38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2071,7 +2071,7 @@ "node_modules/@nhsdigital/eps-cdk-constructs": { "version": "1.6.0", "resolved": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", - "integrity": "sha512-pvgW6Wp17YS04fXeFDldma91V/Uc8xdGZDRSg08//tBQ5O+TxYSJ3E+pF0q6bu2wyuG0QqCMD703BLjbATMi8g==", + "integrity": "sha512-pg9Hw7iAGXJbbiEBta52jOHQFjR8v11OM/B+seg46yjZkbDaE8bSJ5luBHvDntnYeduPY2/joR2/o2mmpRNhyQ==", "license": "MIT", "dependencies": { "@aws-sdk/client-cloudformation": "^3.1018.0", @@ -7214,6 +7214,7 @@ }, "node_modules/semver": { "version": "7.7.3", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8019,6 +8020,7 @@ }, "node_modules/yaml": { "version": "1.10.2", + "dev": true, "license": "ISC", "engines": { "node": ">= 6" diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts index 01283940a..a874b4fc4 100644 --- a/packages/cdk/bin/PfPApiApp.ts +++ b/packages/cdk/bin/PfPApiApp.ts @@ -24,6 +24,9 @@ function main() { targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer"), toggleGetStatusUpdates: getConfigFromEnvVar("toggleGetStatusUpdates"), allowNhsNumberOverride: getConfigFromEnvVar("allowNhsNumberOverride"), + tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue"), + tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue"), + tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue"), mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile"), // CSOC API GW log destination - do not change csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", diff --git a/packages/cdk/resources/Functions.ts b/packages/cdk/resources/Functions.ts index c8b2d89f7..f70ce42cf 100644 --- a/packages/cdk/resources/Functions.ts +++ b/packages/cdk/resources/Functions.ts @@ -1,7 +1,8 @@ -import {Aws, Fn, RemovalPolicy} from "aws-cdk-lib" -import {ManagedPolicy, PolicyStatement} from "aws-cdk-lib/aws-iam" +import {Fn, RemovalPolicy} from "aws-cdk-lib" +import {IManagedPolicy, ManagedPolicy} from "aws-cdk-lib/aws-iam" import {Construct} from "constructs" import {TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" +import {ACCOUNT_RESOURCES} from "@nhsdigital/eps-cdk-constructs/lib/src/constants.js" import {Code, LayerVersion} from "aws-cdk-lib/aws-lambda" import {join, resolve} from "node:path" @@ -14,6 +15,7 @@ export interface FunctionsProps { readonly targetServiceSearchServer: string readonly toggleGetStatusUpdates: string readonly allowNhsNumberOverride: string + readonly getPfPParametersPolicy: IManagedPolicy readonly logRetentionInDays: number readonly logLevel: string } @@ -28,37 +30,20 @@ export class Functions extends Construct { // Imports const lambdaAccessSecretsPolicy = ManagedPolicy.fromManagedPolicyArn( - this, "lambdaAccessSecretsPolicy", Fn.importValue("account-resources:LambdaAccessSecretsPolicy")) + this, "lambdaAccessSecretsPolicy", ACCOUNT_RESOURCES.LambdaAccessSecretsPolicy) const lambdaDecryptSecretsKMSPolicy = ManagedPolicy.fromManagedPolicyArn( - this, "lambdaDecryptSecretsKMSPolicy", Fn.importValue("account-resources:LambdaDecryptSecretsKMSPolicy")) - - const getPfPParametersPolicy = new ManagedPolicy(this, "GetPfPParametersPolicy", { - description: "Read test case SSM parameters", - statements: [ - new PolicyStatement({ - actions: [ - "ssm:GetParameter", - "ssm:GetParameters" - ], - resources: [ - `arn:aws:ssm:${Aws.REGION}:${Aws.ACCOUNT_ID}:parameter/${props.stackName}-TC007NHSNumber`, - `arn:aws:ssm:${Aws.REGION}:${Aws.ACCOUNT_ID}:parameter/${props.stackName}-TC008NHSNumber`, - `arn:aws:ssm:${Aws.REGION}:${Aws.ACCOUNT_ID}:parameter/${props.stackName}-TC009NHSNumber` - ] - }) - ] - }) + this, "lambdaDecryptSecretsKMSPolicy", ACCOUNT_RESOURCES.LambdaDecryptSecretsKMSPolicy) const lambdaDefaultEnvironmentVariables: {[key: string]: string} = { STACK_NAME: props.stackName, TargetSpineServer: props.targetSpineServer, TargetServiceSearchServer: props.targetServiceSearchServer, - SpinePrivateKeyARN: Fn.importValue("account-resources:SpinePrivateKey"), - SpinePublicCertificateARN: Fn.importValue("account-resources:SpinePublicCertificate"), - SpineASIDARN: Fn.importValue("account-resources:SpineASID"), - SpinePartyKeyARN: Fn.importValue("account-resources:SpinePartyKey"), - SpineCAChainARN: Fn.importValue("account-resources:SpineCAChain"), + SpinePrivateKeyARN: ACCOUNT_RESOURCES.SpinePrivateKeyARN, + SpinePublicCertificateARN: ACCOUNT_RESOURCES.SpinePublicCertificateARN, + SpineASIDARN: ACCOUNT_RESOURCES.SpineASIDARN, + SpinePartyKeyARN: ACCOUNT_RESOURCES.SpinePartyKeyARN, + SpineCAChainARN: ACCOUNT_RESOURCES.SpineCAChainARN, ServiceSearch3ApiKeyARN: Fn.importValue("pfp-PfP-ServiceSearch-API-Key") } @@ -85,7 +70,7 @@ export class Functions extends Construct { additionalPolicies: [ lambdaAccessSecretsPolicy, lambdaDecryptSecretsKMSPolicy, - getPfPParametersPolicy + props.getPfPParametersPolicy ], logRetentionInDays: props.logRetentionInDays, logLevel: props.logLevel, @@ -104,7 +89,7 @@ export class Functions extends Construct { EXPECT_STATUS_UPDATES: props.toggleGetStatusUpdates }, additionalPolicies: [ - getPfPParametersPolicy + props.getPfPParametersPolicy ], logRetentionInDays: props.logRetentionInDays, logLevel: props.logLevel, diff --git a/packages/cdk/stacks/PfPApiStack.ts b/packages/cdk/stacks/PfPApiStack.ts index b6f5fa364..7453a3036 100644 --- a/packages/cdk/stacks/PfPApiStack.ts +++ b/packages/cdk/stacks/PfPApiStack.ts @@ -4,6 +4,7 @@ import {Functions} from "../resources/Functions" import {StateMachines} from "../resources/StateMachines" import {Apis} from "../resources/Apis" import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" +import Parameters from "../resources/Parameters" export interface PfPApiStackProps extends StandardStackProps { readonly stackName: string @@ -13,6 +14,9 @@ export interface PfPApiStackProps extends StandardStackProps { readonly targetServiceSearchServer: string readonly toggleGetStatusUpdates: string readonly allowNhsNumberOverride: string + readonly tc007NhsNumberValue: string + readonly tc008NhsNumberValue: string + readonly tc009NhsNumberValue: string readonly mutualTlsTrustStoreKey: string | undefined readonly csocApiGatewayDestination: string readonly forwardCsocLogs: boolean @@ -23,6 +27,13 @@ export class PfPApiStack extends Stack { super(scope, id, props) // Resources + const parameters = new Parameters(this, "SsmParameters", { + stackName: props.stackName, + tc007NhsNumberValue: props.tc007NhsNumberValue, + tc008NhsNumberValue: props.tc008NhsNumberValue, + tc009NhsNumberValue: props.tc009NhsNumberValue + }) + const functions = new Functions(this, "Functions", { stackName: props.stackName, version: props.version, @@ -32,6 +43,7 @@ export class PfPApiStack extends Stack { targetServiceSearchServer: props.targetServiceSearchServer, toggleGetStatusUpdates: props.toggleGetStatusUpdates, allowNhsNumberOverride: props.allowNhsNumberOverride, + getPfPParametersPolicy: parameters.readParametersPolicy, logRetentionInDays: props.logRetentionInDays, logLevel: props.logLevel }) diff --git a/packages/cdk/tests/synth.test.ts b/packages/cdk/tests/synth.test.ts index 0ab4de83c..2e865986d 100644 --- a/packages/cdk/tests/synth.test.ts +++ b/packages/cdk/tests/synth.test.ts @@ -50,6 +50,9 @@ describe("CDK synth smoke tests", () => { CDK_CONFIG_targetServiceSearchServer: "https://live/service-search-api/", CDK_CONFIG_toggleGetStatusUpdates: "true", CDK_CONFIG_allowNhsNumberOverride: "false", + CDK_CONFIG_tc007NhsNumberValue: "9000000009", + CDK_CONFIG_tc008NhsNumberValue: "9000000017", + CDK_CONFIG_tc009NhsNumberValue: "9000000025", CDK_CONFIG_forwardCsocLogs: "false" } }) From 461aa46bd0eaf2b6951346047569ed9b4c30cb9f Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:39:25 +0000 Subject: [PATCH 14/22] fix: use revised parameters construct --- package-lock.json | 2 +- packages/cdk/bin/PfPApiApp.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0cc213e38..77f2b062e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2071,7 +2071,7 @@ "node_modules/@nhsdigital/eps-cdk-constructs": { "version": "1.6.0", "resolved": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", - "integrity": "sha512-pg9Hw7iAGXJbbiEBta52jOHQFjR8v11OM/B+seg46yjZkbDaE8bSJ5luBHvDntnYeduPY2/joR2/o2mmpRNhyQ==", + "integrity": "sha512-lXHsiE/OST8I2RxSN/WtlJiu8cjvg56rQla/4IxPCYcRzt0OxidhWzppQQqFizDUx0RS/rWkjG3j10DI7Q8Ysg==", "license": "MIT", "dependencies": { "@aws-sdk/client-cloudformation": "^3.1018.0", diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts index a874b4fc4..ceb6c2a31 100644 --- a/packages/cdk/bin/PfPApiApp.ts +++ b/packages/cdk/bin/PfPApiApp.ts @@ -24,9 +24,9 @@ function main() { targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer"), toggleGetStatusUpdates: getConfigFromEnvVar("toggleGetStatusUpdates"), allowNhsNumberOverride: getConfigFromEnvVar("allowNhsNumberOverride"), - tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue"), - tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue"), - tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue"), + tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue", ""), + tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue", ""), + tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue", ""), mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile"), // CSOC API GW log destination - do not change csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", From dbecf328604345cfb37fa6a68cd1d02d65ce8991 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:56:28 +0000 Subject: [PATCH 15/22] chore: add missing file, sane defaults for TC params --- packages/cdk/bin/PfPApiApp.ts | 6 ++-- packages/cdk/resources/Parameters.ts | 53 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 packages/cdk/resources/Parameters.ts diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts index ceb6c2a31..ee330e649 100644 --- a/packages/cdk/bin/PfPApiApp.ts +++ b/packages/cdk/bin/PfPApiApp.ts @@ -24,9 +24,9 @@ function main() { targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer"), toggleGetStatusUpdates: getConfigFromEnvVar("toggleGetStatusUpdates"), allowNhsNumberOverride: getConfigFromEnvVar("allowNhsNumberOverride"), - tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue", ""), - tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue", ""), - tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue", ""), + tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue", "not_in_use"), + tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue", "not_in_use"), + tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue", "not_in_use"), mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile"), // CSOC API GW log destination - do not change csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", diff --git a/packages/cdk/resources/Parameters.ts b/packages/cdk/resources/Parameters.ts new file mode 100644 index 000000000..24d01271f --- /dev/null +++ b/packages/cdk/resources/Parameters.ts @@ -0,0 +1,53 @@ +import {ManagedPolicy} from "aws-cdk-lib/aws-iam" +import {Construct} from "constructs" +import { + SsmParameterDefinition, + SsmParametersConstruct, + SsmParametersConstructProps +} from "@nhsdigital/eps-cdk-constructs" + +export interface ParametersProps { + readonly stackName: string + readonly tc007NhsNumberValue: string + readonly tc008NhsNumberValue: string + readonly tc009NhsNumberValue: string +} + +export default class Parameters extends Construct { + public readonly readParametersPolicy: ManagedPolicy + + public constructor(scope: Construct, id: string, props: ParametersProps) { + super(scope, id) + + const parameterDefinitions: Array = [ + { + id: "TC007NHSNumber", + nameSuffix: "TC007NHSNumber", + description: "List of NHS numbers that will trigger 'temporarily unavailable' response for testing purposes.", + value: props.tc007NhsNumberValue + }, + { + id: "TC008NHSNumber", + nameSuffix: "TC008NHSNumber", + description: "List of NHS numbers that will trigger '500 system error' response for testing purposes.", + value: props.tc008NhsNumberValue + }, + { + id: "TC009NHSNumber", + nameSuffix: "TC009NHSNumber", + description: + "List of NHS numbers that will trigger 'one or more prescriptions missing' response for testing purposes.", + value: props.tc009NhsNumberValue + } + ] + + const ssmParametersProps: SsmParametersConstructProps = { + namePrefix: props.stackName, + parameters: parameterDefinitions, + readPolicyDescription: "Allows reading SSM parameters" + } + + const ssmParameters = new SsmParametersConstruct(this, "PfPApiSsmParameters", ssmParametersProps) + this.readParametersPolicy = ssmParameters.readParametersPolicy + } +} From 94a33a8e8beeeb478a5dd16e406391f506fb0c43 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Tue, 31 Mar 2026 14:08:16 +0000 Subject: [PATCH 16/22] feat: SSv3 API key from existing secret by name, not ARN --- packages/cdk/bin/PfPApiApp.ts | 1 + packages/cdk/resources/Functions.ts | 5 +++-- packages/cdk/stacks/PfPApiStack.ts | 2 ++ .../src/live-serviceSearch-client.ts | 10 +++++----- .../tests/live-serviceSearch-client.test.ts | 6 ++++-- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts index ee330e649..926d52ec5 100644 --- a/packages/cdk/bin/PfPApiApp.ts +++ b/packages/cdk/bin/PfPApiApp.ts @@ -20,6 +20,7 @@ function main() { stackName: calculateVersionedStackName(getConfigFromEnvVar("stackName"), props), logRetentionInDays: getNumberConfigFromEnvVar("logRetentionInDays"), logLevel: getConfigFromEnvVar("logLevel"), + serviceSearchApiKeySecretName: getConfigFromEnvVar("serviceSearchApiKeySecretName", "pfp-PfP-ServiceSearch-API-Key"), targetSpineServer: getConfigFromEnvVar("targetSpineServer"), targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer"), toggleGetStatusUpdates: getConfigFromEnvVar("toggleGetStatusUpdates"), diff --git a/packages/cdk/resources/Functions.ts b/packages/cdk/resources/Functions.ts index f70ce42cf..c88bf0818 100644 --- a/packages/cdk/resources/Functions.ts +++ b/packages/cdk/resources/Functions.ts @@ -1,4 +1,4 @@ -import {Fn, RemovalPolicy} from "aws-cdk-lib" +import {RemovalPolicy} from "aws-cdk-lib" import {IManagedPolicy, ManagedPolicy} from "aws-cdk-lib/aws-iam" import {Construct} from "constructs" import {TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" @@ -13,6 +13,7 @@ export interface FunctionsProps { readonly deploymentEnvironment: string readonly targetSpineServer: string readonly targetServiceSearchServer: string + readonly serviceSearchApiKeySecretName: string readonly toggleGetStatusUpdates: string readonly allowNhsNumberOverride: string readonly getPfPParametersPolicy: IManagedPolicy @@ -44,7 +45,7 @@ export class Functions extends Construct { SpineASIDARN: ACCOUNT_RESOURCES.SpineASIDARN, SpinePartyKeyARN: ACCOUNT_RESOURCES.SpinePartyKeyARN, SpineCAChainARN: ACCOUNT_RESOURCES.SpineCAChainARN, - ServiceSearch3ApiKeyARN: Fn.importValue("pfp-PfP-ServiceSearch-API-Key") + ServiceSearch3ApiKeyName: props.serviceSearchApiKeySecretName } const getSecretsLambdaLayer = new LayerVersion(this, "GetSecretsLambdaLayer", { diff --git a/packages/cdk/stacks/PfPApiStack.ts b/packages/cdk/stacks/PfPApiStack.ts index 7453a3036..b5493195d 100644 --- a/packages/cdk/stacks/PfPApiStack.ts +++ b/packages/cdk/stacks/PfPApiStack.ts @@ -12,6 +12,7 @@ export interface PfPApiStackProps extends StandardStackProps { readonly logLevel: string readonly targetSpineServer: string readonly targetServiceSearchServer: string + readonly serviceSearchApiKeySecretName: string readonly toggleGetStatusUpdates: string readonly allowNhsNumberOverride: string readonly tc007NhsNumberValue: string @@ -42,6 +43,7 @@ export class PfPApiStack extends Stack { targetSpineServer: props.targetSpineServer, targetServiceSearchServer: props.targetServiceSearchServer, toggleGetStatusUpdates: props.toggleGetStatusUpdates, + serviceSearchApiKeySecretName: props.serviceSearchApiKeySecretName, allowNhsNumberOverride: props.allowNhsNumberOverride, getPfPParametersPolicy: parameters.readParametersPolicy, logRetentionInDays: props.logRetentionInDays, diff --git a/packages/serviceSearchClient/src/live-serviceSearch-client.ts b/packages/serviceSearchClient/src/live-serviceSearch-client.ts index f3c2f7103..ffd4e63b2 100644 --- a/packages/serviceSearchClient/src/live-serviceSearch-client.ts +++ b/packages/serviceSearchClient/src/live-serviceSearch-client.ts @@ -133,14 +133,14 @@ export class LiveServiceSearchClient implements ServiceSearchClient { private async loadApiKeyFromSecretsManager(): Promise { try { - const secretArn = process.env.ServiceSearch3ApiKeyARN - if (!secretArn) { - this.logger.error("ServiceSearch3ApiKeyARN environment variable is not set") + const secretId = process.env.ServiceSearch3ApiKeyName ?? process.env.ServiceSearch3ApiKeyARN + if (!secretId) { + this.logger.error("ServiceSearch3ApiKeyName or ServiceSearch3ApiKeyARN environment variable is not set") return undefined } - this.logger.info("Loading ServiceSearch API key from Secrets Manager", {secretArn}) + this.logger.info("Loading ServiceSearch API key from Secrets Manager", {secretId}) - const secret = await getSecret(secretArn, { + const secret = await getSecret(secretId, { maxAge: 300 // Cache for 5 minutes }) diff --git a/packages/serviceSearchClient/tests/live-serviceSearch-client.test.ts b/packages/serviceSearchClient/tests/live-serviceSearch-client.test.ts index df47fc7a5..34a71c444 100644 --- a/packages/serviceSearchClient/tests/live-serviceSearch-client.test.ts +++ b/packages/serviceSearchClient/tests/live-serviceSearch-client.test.ts @@ -60,6 +60,7 @@ describe("live serviceSearch client", () => { beforeEach(() => { process.env.TargetServiceSearchServer = "live" process.env.ServiceSearch3ApiKey = "test-key" + delete process.env.ServiceSearch3ApiKeyName delete process.env.ServiceSearch3ApiKeyARN logger = new Logger({serviceName: "svcClientTest"}) @@ -68,8 +69,9 @@ describe("live serviceSearch client", () => { vi.restoreAllMocks() }) - test("logs error when ServiceSearch3ApiKeyARN is missing", async () => { + test("logs error when ServiceSearch3ApiKeyName and ServiceSearch3ApiKeyARN are missing", async () => { delete process.env.ServiceSearch3ApiKey + delete process.env.ServiceSearch3ApiKeyName delete process.env.ServiceSearch3ApiKeyARN client = new LiveServiceSearchClient(logger) @@ -90,7 +92,7 @@ describe("live serviceSearch client", () => { await client.searchService("ABC123", dummyCorrelationId) expect(errorSpy).toHaveBeenCalledWith( - "ServiceSearch3ApiKeyARN environment variable is not set" + "ServiceSearch3ApiKeyName or ServiceSearch3ApiKeyARN environment variable is not set" ) }) From 6cc0895e501af7efde6fd9932d06878fa8b65240 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Wed, 1 Apr 2026 08:24:19 +0000 Subject: [PATCH 17/22] feat: sandbox app --- packages/cdk/bin/PfPApiSandboxApp.ts | 38 ++++++++++++++++++----- packages/cdk/stacks/PfPApiSandboxStack.ts | 36 +++++++++++++++++++-- packages/cdk/tests/synth.test.ts | 4 +-- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/packages/cdk/bin/PfPApiSandboxApp.ts b/packages/cdk/bin/PfPApiSandboxApp.ts index e3ebe54c4..085719e2a 100644 --- a/packages/cdk/bin/PfPApiSandboxApp.ts +++ b/packages/cdk/bin/PfPApiSandboxApp.ts @@ -1,11 +1,33 @@ -import {createApp} from "@nhsdigital/eps-cdk-constructs" +import { + calculateVersionedStackName, + createApp, + getConfigFromEnvVar, + getNumberConfigFromEnvVar +} from "@nhsdigital/eps-cdk-constructs" import {PfPApiSandboxStack} from "../stacks/PfPApiSandboxStack" -const {app, props} = createApp({ - productName: "Prescriptions for Patients API", - appName: "PfPApiSandboxApp", - repoName: "prescriptionsforpatients", - driftDetectionGroup: "pfp-api" -}) +function main() { + const {app, props} = createApp({ + productName: "Prescriptions for Patients API", + appName: "PfPApiSandboxApp", + repoName: "prescriptionsforpatients", + driftDetectionGroup: "pfp-api" + }) -new PfPApiSandboxStack(app, "PfPApiSandboxStack", props) + new PfPApiSandboxStack(app, "PfPApiSandboxStack", { + ...props, + stackName: calculateVersionedStackName(getConfigFromEnvVar("stackName", "pfp-sandbox"), props), + targetSpineServer: getConfigFromEnvVar("targetSpineServer", "none"), + targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer", "none"), + logRetentionInDays: getNumberConfigFromEnvVar("logRetentionInDays", "30"), + logLevel: getConfigFromEnvVar("logLevel", "INFO"), + mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile", "none") + }) +} + +try { + main() +} catch (error) { + console.error(error) + process.exit(1) +} diff --git a/packages/cdk/stacks/PfPApiSandboxStack.ts b/packages/cdk/stacks/PfPApiSandboxStack.ts index 49d392259..87135905f 100644 --- a/packages/cdk/stacks/PfPApiSandboxStack.ts +++ b/packages/cdk/stacks/PfPApiSandboxStack.ts @@ -1,10 +1,42 @@ import {Stack, App} from "aws-cdk-lib" import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" +import {SandboxFunctions} from "../resources/SandboxFunctions" +import {SandboxApis} from "../resources/SandboxApis" +import {nagSuppressions} from "../nagSuppressions" + +export interface PfPApiSandboxStackProps extends StandardStackProps { + readonly stackName: string + readonly targetSpineServer: string + readonly targetServiceSearchServer: string + readonly logRetentionInDays: number + readonly logLevel: string + readonly mutualTlsTrustStoreKey: string | undefined +} export class PfPApiSandboxStack extends Stack { - public constructor(scope: App, id: string, props: StandardStackProps){ + public constructor(scope: App, id: string, props: PfPApiSandboxStackProps){ super(scope, id, props) - // PLACEHOLDER FOR SANDBOX RESOURCES + const functions = new SandboxFunctions(this, "Functions", { + stackName: props.stackName, + version: props.version, + commitId: props.commitId, + targetSpineServer: props.targetSpineServer, + targetServiceSearchServer: props.targetServiceSearchServer, + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel + }) + + new SandboxApis(this, "Apis", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + mutualTlsTrustStoreKey: props.mutualTlsTrustStoreKey, + // CSOC API GW log destination - do not change + csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", + forwardCsocLogs: false, + functions: functions.functions + }) + + nagSuppressions(this) } } diff --git a/packages/cdk/tests/synth.test.ts b/packages/cdk/tests/synth.test.ts index 2e865986d..45720d8a9 100644 --- a/packages/cdk/tests/synth.test.ts +++ b/packages/cdk/tests/synth.test.ts @@ -34,7 +34,7 @@ describe("CDK synth smoke tests", () => { env: createBaseEnv() }) }).not.toThrow() - }) + }, 30000) it("synthesizes the main app", () => { expect(() => { @@ -57,5 +57,5 @@ describe("CDK synth smoke tests", () => { } }) }).not.toThrow() - }) + }, 30000) }) From 3147b3a742a72dab331f98b36a5defcd673b1c95 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Wed, 1 Apr 2026 12:00:17 +0000 Subject: [PATCH 18/22] fix: getConfigFromEnvVar calls --- package-lock.json | 2 +- packages/cdk/bin/PfPApiApp.ts | 10 ++++++---- packages/cdk/bin/PfPApiSandboxApp.ts | 14 ++++++++------ packages/cdk/tests/synth.test.ts | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 77f2b062e..4e29f25c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2071,7 +2071,7 @@ "node_modules/@nhsdigital/eps-cdk-constructs": { "version": "1.6.0", "resolved": "file:nhsdigital-eps-cdk-constructs-1.6.0.tgz", - "integrity": "sha512-lXHsiE/OST8I2RxSN/WtlJiu8cjvg56rQla/4IxPCYcRzt0OxidhWzppQQqFizDUx0RS/rWkjG3j10DI7Q8Ysg==", + "integrity": "sha512-fFbcRQ7cbbbcfpcliT+0zAkXsZaUjbY/9m/ST6waA/yc3wl7vSrMzYJEpkwUmOaX9U+MfWmKx5FPjOuTeB75BQ==", "license": "MIT", "dependencies": { "@aws-sdk/client-cloudformation": "^3.1018.0", diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts index 926d52ec5..35f92aa02 100644 --- a/packages/cdk/bin/PfPApiApp.ts +++ b/packages/cdk/bin/PfPApiApp.ts @@ -1,4 +1,5 @@ import { + CDK_ENV_PREFIX, calculateVersionedStackName, createApp, getBooleanConfigFromEnvVar, @@ -20,14 +21,15 @@ function main() { stackName: calculateVersionedStackName(getConfigFromEnvVar("stackName"), props), logRetentionInDays: getNumberConfigFromEnvVar("logRetentionInDays"), logLevel: getConfigFromEnvVar("logLevel"), - serviceSearchApiKeySecretName: getConfigFromEnvVar("serviceSearchApiKeySecretName", "pfp-PfP-ServiceSearch-API-Key"), + serviceSearchApiKeySecretName: getConfigFromEnvVar("serviceSearchApiKeySecretName", + CDK_ENV_PREFIX, "pfp-PfP-ServiceSearch-API-Key"), targetSpineServer: getConfigFromEnvVar("targetSpineServer"), targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer"), toggleGetStatusUpdates: getConfigFromEnvVar("toggleGetStatusUpdates"), allowNhsNumberOverride: getConfigFromEnvVar("allowNhsNumberOverride"), - tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue", "not_in_use"), - tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue", "not_in_use"), - tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue", "not_in_use"), + tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue", CDK_ENV_PREFIX, "not_in_use"), + tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue", CDK_ENV_PREFIX, "not_in_use"), + tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue", CDK_ENV_PREFIX, "not_in_use"), mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile"), // CSOC API GW log destination - do not change csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", diff --git a/packages/cdk/bin/PfPApiSandboxApp.ts b/packages/cdk/bin/PfPApiSandboxApp.ts index 085719e2a..d348e040c 100644 --- a/packages/cdk/bin/PfPApiSandboxApp.ts +++ b/packages/cdk/bin/PfPApiSandboxApp.ts @@ -1,5 +1,6 @@ import { calculateVersionedStackName, + CDK_ENV_PREFIX, createApp, getConfigFromEnvVar, getNumberConfigFromEnvVar @@ -16,12 +17,13 @@ function main() { new PfPApiSandboxStack(app, "PfPApiSandboxStack", { ...props, - stackName: calculateVersionedStackName(getConfigFromEnvVar("stackName", "pfp-sandbox"), props), - targetSpineServer: getConfigFromEnvVar("targetSpineServer", "none"), - targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer", "none"), - logRetentionInDays: getNumberConfigFromEnvVar("logRetentionInDays", "30"), - logLevel: getConfigFromEnvVar("logLevel", "INFO"), - mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile", "none") + stackName: calculateVersionedStackName(getConfigFromEnvVar("stackName", CDK_ENV_PREFIX, "pfp-sandbox"), props), + targetSpineServer: getConfigFromEnvVar("targetSpineServer", CDK_ENV_PREFIX, "none"), + targetServiceSearchServer: getConfigFromEnvVar("targetServiceSearchServer", CDK_ENV_PREFIX, "none"), + logRetentionInDays: getNumberConfigFromEnvVar("logRetentionInDays", CDK_ENV_PREFIX, "30"), + logLevel: getConfigFromEnvVar("logLevel", CDK_ENV_PREFIX, "INFO"), + mutualTlsTrustStoreKey: props.isPullRequest ? + undefined : getConfigFromEnvVar("trustStoreFile", CDK_ENV_PREFIX, "none") }) } diff --git a/packages/cdk/tests/synth.test.ts b/packages/cdk/tests/synth.test.ts index 45720d8a9..208bd92cc 100644 --- a/packages/cdk/tests/synth.test.ts +++ b/packages/cdk/tests/synth.test.ts @@ -24,7 +24,7 @@ describe("CDK synth smoke tests", () => { stdio: "pipe" }) }).not.toThrow() - }) + }, 30000) it("synthesizes the sandbox app", () => { expect(() => { From 5e835278d8b7690cbadab501e6960879339393aa Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Thu, 2 Apr 2026 13:30:42 +0000 Subject: [PATCH 19/22] ops: cdk workflows, currently both cdk and sam --- .../actions/install_dependencies/action.yml | 35 ++ .github/workflows/cdk_package_code.yml | 66 ++++ .github/workflows/cdk_release_code.yml | 348 ++++++++++++++++++ .github/workflows/pull_request.yml | 44 ++- 4 files changed, 491 insertions(+), 2 deletions(-) create mode 100644 .github/actions/install_dependencies/action.yml create mode 100644 .github/workflows/cdk_package_code.yml create mode 100644 .github/workflows/cdk_release_code.yml diff --git a/.github/actions/install_dependencies/action.yml b/.github/actions/install_dependencies/action.yml new file mode 100644 index 000000000..108096bb8 --- /dev/null +++ b/.github/actions/install_dependencies/action.yml @@ -0,0 +1,35 @@ +name: "Install dependencies" +description: "Install dependencies including caching of npm packages" + +inputs: + npm-required: + description: "Set to true if npm dependencies are already installed" + required: false + default: "true" + GITHUB_TOKEN: + description: "GitHub token to access private npm packages" + required: true + +runs: + using: "composite" + steps: + - name: Setting up .npmrc + if: ${{ inputs.npm-required == 'true' }} + env: + NODE_AUTH_TOKEN: ${{ inputs.GITHUB_TOKEN }} + shell: bash + run: | + echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc + echo "@nhsdigital:registry=https://npm.pkg.github.com" >> ~/.npmrc + + - name: Cache npm dependencies + if: ${{ inputs.npm-required == 'true' }} + uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 + with: + path: ./node_modules + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + + - name: make install + if: ${{ inputs.npm-required == 'true' }} + shell: bash + run: make install diff --git a/.github/workflows/cdk_package_code.yml b/.github/workflows/cdk_package_code.yml new file mode 100644 index 000000000..1ce76afb0 --- /dev/null +++ b/.github/workflows/cdk_package_code.yml @@ -0,0 +1,66 @@ +name: cdk package code + +on: + workflow_call: + inputs: + pinned_image: + type: string + required: true + +jobs: + package_code: + runs-on: ubuntu-22.04 + container: + image: ${{ inputs.pinned_image }} + options: --user 1001:1001 --group-add 128 + defaults: + run: + shell: bash + permissions: + id-token: write + contents: read + packages: read + steps: + - name: copy .tool-versions + run: | + cp /home/vscode/.tool-versions "$HOME/.tool-versions" + cp /home/vscode/.tool-versions ./.tool-versions + + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + ref: ${{ github.head_ref || github.ref_name }} + + - name: Setting up .npmrc + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}" >> ~/.npmrc + echo "@nhsdigital:registry=https://npm.pkg.github.com" >> ~/.npmrc + + - name: make install and compile + run: | + make install + make compile + + - name: download the get secrets lambda layer + run: | + make download-get-secrets-layer + + - name: Tar files + run: | + tar -cf artifact.tar \ + .github \ + packages \ + node_modules \ + package.json \ + package-lock.json \ + tsconfig.defaults.json \ + tsconfig.build.json \ + Makefile + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + name: upload build artifact + with: + name: build_artifact + path: artifact.tar diff --git a/.github/workflows/cdk_release_code.yml b/.github/workflows/cdk_release_code.yml new file mode 100644 index 000000000..4f53ac202 --- /dev/null +++ b/.github/workflows/cdk_release_code.yml @@ -0,0 +1,348 @@ +name: cdk release code + +on: + workflow_call: + inputs: + REAL_CDK_DEPLOYMENT: + type: boolean + default: false + IS_PULL_REQUEST: + type: boolean + default: false + STACK_NAME: + required: true + type: string + TARGET_ENVIRONMENT: + required: true + type: string + APIGEE_ENVIRONMENT: + required: true + type: string + ENABLE_MUTUAL_TLS: + required: true + type: boolean + BUILD_ARTIFACT: + required: true + type: string + TRUSTSTORE_FILE: + required: true + type: string + VERSION_NUMBER: + required: true + type: string + COMMIT_ID: + required: true + type: string + CDK_APP_NAME: + type: string + default: PfPApiApp + LOG_LEVEL: + required: true + type: string + LOG_RETENTION_DAYS: + required: true + type: string + CREATE_INT_RELEASE_NOTES: + type: boolean + default: false + CREATE_INT_RC_RELEASE_NOTES: + type: boolean + default: false + CREATE_PROD_RELEASE_NOTES: + type: boolean + default: false + MARK_JIRA_RELEASED: + type: boolean + default: false + TOGGLE_GET_STATUS_UPDATES: + type: boolean + default: false + RUN_REGRESSION_TESTS: + type: boolean + default: true + ENABLE_ALERTS: + type: boolean + default: true + STATE_MACHINE_LOG_LEVEL: + type: string + REGRESSION_TEST_PRODUCT: + type: string + FORWARD_CSOC_LOGS: + required: true + type: boolean + TC007_NHS_NUMBERS: + required: false + type: string + TC008_NHS_NUMBERS: + required: false + type: string + TC009_NHS_NUMBERS: + required: false + type: string + DEPLOY_APIGEE: + type: boolean + default: true + MTLS_KEY: + type: string + required: true + ALLOW_NHS_NUMBER_OVERRIDE: + required: true + type: boolean + REGRESSION_TEST_NON_PROXYGEN: + type: boolean + UPDATE_GH_PAGES_RELEASE_TAG: + type: boolean + default: false + pinned_image: + type: string + required: true + secrets: + CLOUD_FORMATION_DEPLOY_ROLE: + required: true + # TODO: copied from tracker, used for delete stacks, needed? + #APIM_STATUS_API_KEY: + # required: true + TARGET_SPINE_SERVER: + required: true + TARGET_SERVICE_SEARCH_SERVER: + required: true + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: + required: false + INT_CLOUD_FORMATION_CHECK_VERSION_ROLE: + required: false + PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE: + required: false + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: + required: false + REGRESSION_TESTS_PEM: + required: false + PROXYGEN_ROLE: + required: false + +jobs: + release_code_and_api: + runs-on: ubuntu-22.04 + environment: ${{ inputs.TARGET_ENVIRONMENT }} + container: + image: ${{ inputs.pinned_image }} + options: --user 1001:1001 --group-add 128 + defaults: + run: + shell: bash + name: deploy cdk app ${{ inputs.CDK_APP_NAME }} + permissions: + id-token: write + contents: write + env: + AWS_MAX_RETRY: 20 + + steps: + - name: copy .tool-versions + run: | + cp /home/vscode/.tool-versions "$HOME/.tool-versions" + + - name: Checkout local github actions + uses: actions/checkout@v5 + with: + fetch-depth: 0 + sparse-checkout: | + .github + + - name: create_int_rc_release_notes + uses: ./.github/actions/update_confluence_jira + if: ${{ inputs.CREATE_INT_RC_RELEASE_NOTES == true }} + with: + TARGET_ENVIRONMENT: int + RELEASE_TAG: ${{ inputs.VERSION_NUMBER }} + CONFLUENCE_PAGE_ID: "768067994" + CREATE_RC_RELEASE_NOTES: true + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + TARGET_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-session-name: aws-pfp-release-code + + - name: download build artifact + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c + with: + name: ${{ inputs.BUILD_ARTIFACT }} + path: . + + - name: extract build artifact + run: tar -xf artifact.tar + + + - name: delete old CDK stacks + if: ${{ inputs.IS_PULL_REQUEST != true }} + run: npm run delete-main-stacks --workspace packages/cdk + shell: bash + env: + AWS_ENVIRONMENT: "${{ inputs.TARGET_ENVIRONMENT }}" + APIGEE_ENVIRONMENT: "${{ inputs.APIGEE_ENVIRONMENT }}" + # APIM_STATUS_API_KEY: "${{ secrets.APIM_STATUS_API_KEY }}" + + - name: install dependencies + uses: ./.github/actions/install_dependencies + with: + npm-required: false + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Show diff + env: + CDK_APP_NAME: ${{ inputs.CDK_APP_NAME }} + REQUIRE_APPROVAL: never + CDK_CONFIG_stackName: ${{ inputs.STACK_NAME }} + CDK_CONFIG_versionNumber: ${{ inputs.VERSION_NUMBER }} + CDK_CONFIG_commitId: ${{ inputs.COMMIT_ID }} + CDK_CONFIG_isPullRequest: ${{ inputs.IS_PULL_REQUEST }} + CDK_CONFIG_environment: ${{ inputs.TARGET_ENVIRONMENT }} + CDK_CONFIG_logRetentionInDays: ${{ inputs.LOG_RETENTION_DAYS }} + CDK_CONFIG_logLevel: ${{ inputs.LOG_LEVEL }} + CDK_CONFIG_targetSpineServer: ${{ secrets.TARGET_SPINE_SERVER }} + CDK_CONFIG_targetServiceSearchServer: ${{ secrets.TARGET_SERVICE_SEARCH_SERVER }} + CDK_CONFIG_toggleGetStatusUpdates: ${{ inputs.TOGGLE_GET_STATUS_UPDATES }} + CDK_CONFIG_allowNhsNumberOverride: ${{ inputs.ALLOW_NHS_NUMBER_OVERRIDE }} + CDK_CONFIG_tc007NhsNumberValue: ${{ inputs.TC007_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc008NhsNumberValue: ${{ inputs.TC008_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc009NhsNumberValue: ${{ inputs.TC009_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_trustStoreFile: ${{ inputs.TRUSTSTORE_FILE }} + CDK_CONFIG_forwardCsocLogs: ${{ inputs.FORWARD_CSOC_LOGS }} + run: npm run cdk-diff --workspace packages/cdk + + - name: Deploy code + env: + CDK_APP_NAME: ${{ inputs.CDK_APP_NAME }} + REQUIRE_APPROVAL: never + CDK_CONFIG_stackName: ${{ inputs.STACK_NAME }} + CDK_CONFIG_versionNumber: ${{ inputs.VERSION_NUMBER }} + CDK_CONFIG_commitId: ${{ inputs.COMMIT_ID }} + CDK_CONFIG_isPullRequest: ${{ inputs.IS_PULL_REQUEST }} + CDK_CONFIG_environment: ${{ inputs.TARGET_ENVIRONMENT }} + CDK_CONFIG_logRetentionInDays: ${{ inputs.LOG_RETENTION_DAYS }} + CDK_CONFIG_logLevel: ${{ inputs.LOG_LEVEL }} + CDK_CONFIG_targetSpineServer: ${{ secrets.TARGET_SPINE_SERVER }} + CDK_CONFIG_targetServiceSearchServer: ${{ secrets.TARGET_SERVICE_SEARCH_SERVER }} + CDK_CONFIG_toggleGetStatusUpdates: ${{ inputs.TOGGLE_GET_STATUS_UPDATES }} + CDK_CONFIG_allowNhsNumberOverride: ${{ inputs.ALLOW_NHS_NUMBER_OVERRIDE }} + CDK_CONFIG_tc007NhsNumberValue: ${{ inputs.TC007_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc008NhsNumberValue: ${{ inputs.TC008_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_tc009NhsNumberValue: ${{ inputs.TC009_NHS_NUMBERS || '9992387920' }} + CDK_CONFIG_trustStoreFile: ${{ inputs.TRUSTSTORE_FILE }} + CDK_CONFIG_forwardCsocLogs: ${{ inputs.FORWARD_CSOC_LOGS }} + run: npm run cdk-deploy --workspace packages/cdk + + - name: get mtls secrets + shell: bash + run: | + mkdir -p ~/.proxygen/tmp + client_private_key_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:PfpClientKeySecret'].Value" --output text) + client_cert_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:PfpClientCertSecret'].Value" --output text) + aws secretsmanager get-secret-value --secret-id "${client_private_key_arn}" --query SecretString --output text > ~/.proxygen/tmp/client_private_key + aws secretsmanager get-secret-value --secret-id "${client_cert_arn}" --query SecretString --output text > ~/.proxygen/tmp/client_cert + + - name: Configure AWS Credentials for api release + if: ${{ inputs.DEPLOY_APIGEE == true && always() && !failure() && !cancelled() }} + uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PROXYGEN_ROLE }} + role-session-name: pfp-api-proxygen + + - name: Deploy PFP API to Apigee + shell: bash + if: ${{ inputs.DEPLOY_APIGEE == true && always() && !failure() && !cancelled() }} + env: + API_TYPE: standard + VERSION_NUMBER: ${{ inputs.VERSION_NUMBER }} + SPEC_PATH: ./packages/specification/dist/prescriptions-for-patients.resolved.json + STACK_NAME: ${{ inputs.STACK_NAME }} + AWS_ENVIRONMENT: ${{ inputs.TARGET_ENVIRONMENT }} + APIGEE_ENVIRONMENT: ${{ inputs.APIGEE_ENVIRONMENT }} + PROXYGEN_PRIVATE_KEY_NAME: PrescriptionsForPatientsProxygenPrivateKey + PROXYGEN_KID: "2026-01-22-PROD-prescriptions-for-patients-v2" + DRY_RUN: false + ENABLE_MUTUAL_TLS: ${{ inputs.ENABLE_MUTUAL_TLS }} + MTLS_KEY: ${{ inputs.MTLS_KEY }} + IS_PULL_REQUEST: ${{ inputs.IS_PULL_REQUEST }} + run: ./.github/scripts/deploy_api.sh + + - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + name: Upload specs + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && always() && !cancelled() }} + with: + name: ${{ inputs.APIGEE_ENVIRONMENT }}-specs + path: | + ./packages/specification/dist/prescriptions-for-patients.resolved.json + + - name: create_int_release_notes + uses: ./.github/actions/update_confluence_jira + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.CREATE_INT_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} + with: + TARGET_ENVIRONMENT: int + CONFLUENCE_PAGE_ID: "768067990" + CREATE_RC_RELEASE_NOTES: false + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + TARGET_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + + - name: create_prod_release_notes + uses: ./.github/actions/update_confluence_jira + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.CREATE_PROD_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} + with: + TARGET_ENVIRONMENT: prod + CONFLUENCE_PAGE_ID: "768067992" + CREATE_RC_RELEASE_NOTES: false + DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + TARGET_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + + - name: mark_released_in_jira + uses: ./.github/actions/mark_jira_released + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.MARK_JIRA_RELEASED == true && always() && !failure() && !cancelled() }} + with: + RELEASE_TAG: ${{ inputs.VERSION_NUMBER }} + DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + + - name: Checkout gh-pages + if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.IS_PULL_REQUEST == false }} + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd + with: + ref: gh-pages + path: gh-pages + + - name: Update release tag in github pages + # if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.IS_PULL_REQUEST == false }} + # Disabled by default; can be explicitly enabled by setting UPDATE_GH_PAGES_RELEASE_TAG to true. + if: ${{ inputs.UPDATE_GH_PAGES_RELEASE_TAG == true && inputs.IS_PULL_REQUEST == false }} + run: | + cd gh-pages + NOW=$(date +'%Y-%m-%dT%H:%M:%S') + echo "tag,release_datetime" > _data/${{ inputs.APIGEE_ENVIRONMENT }}_latest.csv + echo "${{ inputs.VERSION_NUMBER }},${NOW}" >> _data/${{ inputs.APIGEE_ENVIRONMENT }}_latest.csv + echo "${{ inputs.VERSION_NUMBER }},${NOW}" >> _data/${{ inputs.APIGEE_ENVIRONMENT }}_deployments.csv + git config user.name github-actions + git config user.email github-actions@github.com + git add _data/${{ inputs.APIGEE_ENVIRONMENT }}_latest.csv + git add _data/${{ inputs.APIGEE_ENVIRONMENT }}_deployments.csv + git commit -m 'update releases for ${{ inputs.APIGEE_ENVIRONMENT }}' + parallel --retries 10 --delay 3 ::: "git pull --rebase && git push" + + regression_tests: + name: Regression Tests + uses: ./.github/workflows/run_regression_tests.yml + # TODO: are always, !fail, !cancelled needed? + if: ${{ always() && !failure() && !cancelled() && inputs.RUN_REGRESSION_TESTS == true }} + needs: [release_code_and_api] + with: + ENVIRONMENT: "${{ inputs.APIGEE_ENVIRONMENT }}" + VERSION_NUMBER: "${{ inputs.VERSION_NUMBER }}" + REGRESSION_TEST_PRODUCT: "${{ inputs.REGRESSION_TEST_PRODUCT }}" + REGRESSION_TEST_NON_PROXYGEN: "${{ inputs.REGRESSION_TEST_NON_PROXYGEN }}" + pinned_image: "${{ inputs.pinned_image }}" + secrets: + REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e49997869..d4c3c7d43 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -19,7 +19,6 @@ jobs: with: verify_published_from_main_image: false - quality_checks: uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks-devcontainer.yml@5ac2707dd9cd60ad127275179495b9c890d74711 needs: [get_config_values] @@ -119,12 +118,53 @@ jobs: TARGET_SPINE_SERVER: ${{ secrets.DEV_TARGET_SPINE_SERVER }} TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.DEV_TARGET_SERVICE_SEARCH_SERVER }} PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} + + package_cdk_code: + needs: [get_issue_number, tag_release, get_config_values] + uses: ./.github/workflows/cdk_package_code.yml + with: + pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} + + release_cdk_code: + needs: [get_issue_number, package_code, get_commit_id, get_config_values] + uses: ./.github/workflows/cdk_release_code.yml + with: + IS_PULL_REQUEST: true + STACK_NAME: pfp-pr-cdk-${{needs.get_issue_number.outputs.issue_number}} + TARGET_ENVIRONMENT: dev + APIGEE_ENVIRONMENT: internal-dev + # TODO: needed? + # APIM_STATUS_API_KEY: ${{ secrets.APIM_STATUS_API_KEY }} + ENABLE_MUTUAL_TLS: false + MTLS_KEY: prescriptions-for-patients-mtls-1 + BUILD_ARTIFACT: build_artifact + TRUSTSTORE_FILE: pfp-truststore-pr.pem + VERSION_NUMBER: PR-${{ needs.get_issue_number.outputs.issue_number }} + COMMIT_ID: ${{ needs.get_commit_id.outputs.commit_id }} + LOG_LEVEL: DEBUG + LOG_RETENTION_DAYS: 30 + TOGGLE_GET_STATUS_UPDATES: true + ENABLE_ALERTS: false + STATE_MACHINE_LOG_LEVEL: ALL + RUN_REGRESSION_TESTS: false # Don't run regression tests on CDK yet + REGRESSION_TEST_PRODUCT: PFP-AWS + FORWARD_CSOC_LOGS: false + DEPLOY_APIGEE: true + ALLOW_NHS_NUMBER_OVERRIDE: true + pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} + secrets: + REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} + CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} + TARGET_SPINE_SERVER: ${{ secrets.DEV_TARGET_SPINE_SERVER }} + TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.DEV_TARGET_SERVICE_SEARCH_SERVER }} + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} + release_sandbox_code: needs: [get_issue_number, package_code, get_commit_id, get_config_values] uses: ./.github/workflows/sam_release_code.yml with: IS_PULL_REQUEST: true - STACK_NAME: pfp-pr-${{needs.get_issue_number.outputs.issue_number}}-sandbox + STACK_NAME: pfp-pr-cdk-${{needs.get_issue_number.outputs.issue_number}}-sandbox ARTIFACT_BUCKET_PREFIX: PR-sandbox-${{needs.get_issue_number.outputs.issue_number}} TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev-sandbox From fbfdc0743f2de66ee5e3671790b25751d894c580 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Thu, 2 Apr 2026 14:51:47 +0000 Subject: [PATCH 20/22] ops: introduce toggle between sam and cdk --- .github/workflows/cdk_release_code.yml | 14 ++-- .github/workflows/pull_request.yml | 73 +++++++++++++++++--- packages/cdk/resources/SandboxApis.ts | 72 +++++++++++++++++++ packages/cdk/resources/SandboxFunctions.ts | 80 ++++++++++++++++++++++ 4 files changed, 223 insertions(+), 16 deletions(-) create mode 100644 packages/cdk/resources/SandboxApis.ts create mode 100644 packages/cdk/resources/SandboxFunctions.ts diff --git a/.github/workflows/cdk_release_code.yml b/.github/workflows/cdk_release_code.yml index 4f53ac202..e1a6f70d6 100644 --- a/.github/workflows/cdk_release_code.yml +++ b/.github/workflows/cdk_release_code.yml @@ -3,7 +3,7 @@ name: cdk release code on: workflow_call: inputs: - REAL_CDK_DEPLOYMENT: + IS_CDK_DEPLOY: type: boolean default: false IS_PULL_REQUEST: @@ -273,7 +273,7 @@ jobs: - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f name: Upload specs - if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && always() && !cancelled() }} + if: ${{ inputs.IS_CDK_DEPLOY == true && always() && !cancelled() }} with: name: ${{ inputs.APIGEE_ENVIRONMENT }}-specs path: | @@ -281,7 +281,7 @@ jobs: - name: create_int_release_notes uses: ./.github/actions/update_confluence_jira - if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.CREATE_INT_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} + if: ${{ inputs.IS_CDK_DEPLOY == true && inputs.CREATE_INT_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} with: TARGET_ENVIRONMENT: int CONFLUENCE_PAGE_ID: "768067990" @@ -292,7 +292,7 @@ jobs: - name: create_prod_release_notes uses: ./.github/actions/update_confluence_jira - if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.CREATE_PROD_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} + if: ${{ inputs.IS_CDK_DEPLOY == true && inputs.CREATE_PROD_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} with: TARGET_ENVIRONMENT: prod CONFLUENCE_PAGE_ID: "768067992" @@ -303,20 +303,20 @@ jobs: - name: mark_released_in_jira uses: ./.github/actions/mark_jira_released - if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.MARK_JIRA_RELEASED == true && always() && !failure() && !cancelled() }} + if: ${{ inputs.IS_CDK_DEPLOY == true && inputs.MARK_JIRA_RELEASED == true && always() && !failure() && !cancelled() }} with: RELEASE_TAG: ${{ inputs.VERSION_NUMBER }} DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} - name: Checkout gh-pages - if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.IS_PULL_REQUEST == false }} + if: ${{ inputs.IS_CDK_DEPLOY == true && inputs.IS_PULL_REQUEST == false }} uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: ref: gh-pages path: gh-pages - name: Update release tag in github pages - # if: ${{ inputs.REAL_CDK_DEPLOYMENT == true && inputs.IS_PULL_REQUEST == false }} + # if: ${{ inputs.IS_CDK_DEPLOY == true && inputs.IS_PULL_REQUEST == false }} # Disabled by default; can be explicitly enabled by setting UPDATE_GH_PAGES_RELEASE_TAG to true. if: ${{ inputs.UPDATE_GH_PAGES_RELEASE_TAG == true && inputs.IS_PULL_REQUEST == false }} run: | diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d4c3c7d43..d2e3a7e8b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -80,14 +80,33 @@ jobs: run: | echo "commit_id=${{ github.sha }}" >> "$GITHUB_OUTPUT" + set_deploy_mode: + runs-on: ubuntu-22.04 + outputs: + is_cdk_deploy: ${{ steps.deploy_mode.outputs.is_cdk_deploy }} + steps: + - name: Set deploy mode from PR title + id: deploy_mode + run: | + echo "is_cdk_deploy=${{ contains(github.event.pull_request.title, '[CDK]') }}" >> "$GITHUB_OUTPUT" + - name: Summarize deploy mode + env: + PR_TITLE: ${{ github.event.pull_request.title }} + IS_CDK_DEPLOY: ${{ steps.deploy_mode.outputs.is_cdk_deploy }} + run: | + echo "PR title: ${PR_TITLE}" >> "$GITHUB_STEP_SUMMARY" + echo "is_cdk_deploy: ${IS_CDK_DEPLOY}" >> "$GITHUB_STEP_SUMMARY" + package_code: - needs: [get_issue_number, tag_release, get_config_values] + if: ${{ needs.set_deploy_mode.outputs.is_cdk_deploy != 'true' }} + needs: [get_issue_number, tag_release, get_config_values, set_deploy_mode] uses: ./.github/workflows/sam_package_code.yml with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} release_code: - needs: [get_issue_number, package_code, get_commit_id, get_config_values] + if: ${{ needs.set_deploy_mode.outputs.is_cdk_deploy != 'true' }} + needs: [get_issue_number, package_code, get_commit_id, get_config_values, set_deploy_mode] uses: ./.github/workflows/sam_release_code.yml with: IS_PULL_REQUEST: true @@ -119,14 +138,47 @@ jobs: TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.DEV_TARGET_SERVICE_SEARCH_SERVER }} PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} + release_sandbox_code: + if: ${{ needs.set_deploy_mode.outputs.is_cdk_deploy != 'true' }} + needs: [get_issue_number, package_code, get_commit_id, get_config_values, set_deploy_mode] + uses: ./.github/workflows/sam_release_code.yml + with: + IS_PULL_REQUEST: true + STACK_NAME: pfp-pr-${{needs.get_issue_number.outputs.issue_number}}-sandbox + ARTIFACT_BUCKET_PREFIX: PR-sandbox-${{needs.get_issue_number.outputs.issue_number}} + TARGET_ENVIRONMENT: dev + APIGEE_ENVIRONMENT: internal-dev-sandbox + ENABLE_MUTUAL_TLS: false + MTLS_KEY: prescriptions-for-patients-mtls-1 + BUILD_ARTIFACT: packaged_sandbox_code + TRUSTSTORE_FILE: pfp-sandbox-truststore.pem + VERSION_NUMBER: PR-${{ needs.get_issue_number.outputs.issue_number }} + COMMIT_ID: ${{ needs.get_commit_id.outputs.commit_id }} + LOG_LEVEL: DEBUG + LOG_RETENTION_DAYS: 30 + STATE_MACHINE_LOG_LEVEL: ALL + RUN_REGRESSION_TESTS: false + FORWARD_CSOC_LOGS: false + DEPLOY_APIGEE: false + ALLOW_NHS_NUMBER_OVERRIDE: true + pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} + secrets: + REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} + CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} + TARGET_SPINE_SERVER: sandbox + TARGET_SERVICE_SEARCH_SERVER: sandbox + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} + package_cdk_code: - needs: [get_issue_number, tag_release, get_config_values] + if: ${{ needs.set_deploy_mode.outputs.is_cdk_deploy == 'true' }} + needs: [get_issue_number, tag_release, get_config_values, set_deploy_mode] uses: ./.github/workflows/cdk_package_code.yml with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} release_cdk_code: - needs: [get_issue_number, package_code, get_commit_id, get_config_values] + if: ${{ needs.set_deploy_mode.outputs.is_cdk_deploy == 'true' }} + needs: [get_issue_number, package_cdk_code, get_commit_id, get_config_values, set_deploy_mode] uses: ./.github/workflows/cdk_release_code.yml with: IS_PULL_REQUEST: true @@ -159,25 +211,28 @@ jobs: TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.DEV_TARGET_SERVICE_SEARCH_SERVER }} PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} - release_sandbox_code: - needs: [get_issue_number, package_code, get_commit_id, get_config_values] - uses: ./.github/workflows/sam_release_code.yml + release_cdk_sandbox_code: + if: ${{ needs.set_deploy_mode.outputs.is_cdk_deploy == 'true' }} + needs: [get_issue_number, package_cdk_code, get_commit_id, get_config_values, set_deploy_mode] + uses: ./.github/workflows/cdk_release_code.yml with: IS_PULL_REQUEST: true STACK_NAME: pfp-pr-cdk-${{needs.get_issue_number.outputs.issue_number}}-sandbox - ARTIFACT_BUCKET_PREFIX: PR-sandbox-${{needs.get_issue_number.outputs.issue_number}} TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev-sandbox ENABLE_MUTUAL_TLS: false MTLS_KEY: prescriptions-for-patients-mtls-1 - BUILD_ARTIFACT: packaged_sandbox_code + BUILD_ARTIFACT: build_artifact TRUSTSTORE_FILE: pfp-sandbox-truststore.pem VERSION_NUMBER: PR-${{ needs.get_issue_number.outputs.issue_number }} COMMIT_ID: ${{ needs.get_commit_id.outputs.commit_id }} LOG_LEVEL: DEBUG LOG_RETENTION_DAYS: 30 + TOGGLE_GET_STATUS_UPDATES: true + ENABLE_ALERTS: false STATE_MACHINE_LOG_LEVEL: ALL RUN_REGRESSION_TESTS: false + REGRESSION_TEST_PRODUCT: PFP-AWS FORWARD_CSOC_LOGS: false DEPLOY_APIGEE: false ALLOW_NHS_NUMBER_OVERRIDE: true diff --git a/packages/cdk/resources/SandboxApis.ts b/packages/cdk/resources/SandboxApis.ts new file mode 100644 index 000000000..55331eba0 --- /dev/null +++ b/packages/cdk/resources/SandboxApis.ts @@ -0,0 +1,72 @@ +import {HttpMethod} from "aws-cdk-lib/aws-lambda" +import { + LambdaEndpoint, + RestApiGateway, + TypescriptLambdaFunction +} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" + +export interface SandboxApisProps { + readonly stackName: string + readonly logRetentionInDays: number + readonly mutualTlsTrustStoreKey: string | undefined + readonly csocApiGatewayDestination: string + readonly forwardCsocLogs: boolean + functions: {[key: string]: TypescriptLambdaFunction} +} + +export class SandboxApis extends Construct { + apis: {[key: string]: RestApiGateway} + endpoints: {[key: string]: Construct} + + public constructor(scope: Construct, id: string, props: SandboxApisProps){ + super(scope, id) + + const apiGateway = new RestApiGateway(this, "ApiGateway", { + stackName: props.stackName, + logRetentionInDays: props.logRetentionInDays, + mutualTlsTrustStoreKey: props.mutualTlsTrustStoreKey, + forwardCsocLogs: props.forwardCsocLogs, + csocApiGatewayDestination: props.csocApiGatewayDestination, + executionPolicies: [ + props.functions.sandbox.executionPolicy, + props.functions.capabilityStatement.executionPolicy, + props.functions.status.executionPolicy + ] + }) + const rootResource = apiGateway.api.root + + const bundleEndpoint = new LambdaEndpoint(this, "SandboxBundleEndpoint", { + parentResource: rootResource, + resourceName: "Bundle", + method: HttpMethod.GET, + restApiGatewayRole: apiGateway.role, + lambdaFunction: props.functions.sandbox + }) + + const capabilityStatementEndpoint = new LambdaEndpoint(this, "CapabilityStatementEndpoint", { + parentResource: rootResource, + resourceName: "metadata", + method: HttpMethod.GET, + restApiGatewayRole: apiGateway.role, + lambdaFunction: props.functions.capabilityStatement + }) + + const statusEndpoint = new LambdaEndpoint(this, "StatusEndpoint", { + parentResource: rootResource, + resourceName: "_status", + method: HttpMethod.GET, + restApiGatewayRole: apiGateway.role, + lambdaFunction: props.functions.status + }) + + this.apis = { + api: apiGateway + } + this.endpoints = { + sandbox: bundleEndpoint, + capabilityStatement: capabilityStatementEndpoint, + status: statusEndpoint + } + } +} diff --git a/packages/cdk/resources/SandboxFunctions.ts b/packages/cdk/resources/SandboxFunctions.ts new file mode 100644 index 000000000..26c5a955f --- /dev/null +++ b/packages/cdk/resources/SandboxFunctions.ts @@ -0,0 +1,80 @@ +import {TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" +import {resolve} from "node:path" + +export interface SandboxFunctionsProps { + readonly stackName: string + readonly version: string + readonly commitId: string + readonly targetSpineServer: string + readonly targetServiceSearchServer: string + readonly logRetentionInDays: number + readonly logLevel: string +} + +const baseDir = resolve(__dirname, "../../..") + +export class SandboxFunctions extends Construct { + functions: {[key: string]: TypescriptLambdaFunction} + + public constructor(scope: Construct, id: string, props: SandboxFunctionsProps) { + super(scope, id) + + const lambdaDefaultEnvironmentVariables: {[key: string]: string} = { + STACK_NAME: props.stackName, + TargetSpineServer: props.targetSpineServer, + TargetServiceSearchServer: props.targetServiceSearchServer + } + + const sandboxLambda = new TypescriptLambdaFunction(this, "SandboxLambda", { + functionName: `${props.stackName}-Sandbox`, + projectBaseDir: baseDir, + packageBasePath: "packages/nhsd-pfp-sandbox", + entryPoint: "src/sandbox.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables + }, + timeoutInSeconds: 30, + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + const capabilityStatementLambda = new TypescriptLambdaFunction(this, "CapabilityStatementLambda", { + functionName: `${props.stackName}-CapabilityStatement`, + projectBaseDir: baseDir, + packageBasePath: "packages/capabilityStatement", + entryPoint: "src/capabilityStatement.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables + }, + timeoutInSeconds: 30, + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + const statusLambda = new TypescriptLambdaFunction(this, "StatusLambda", { + functionName: `${props.stackName}-status`, + projectBaseDir: baseDir, + packageBasePath: "packages/statusLambda", + entryPoint: "src/statusLambda.ts", + environmentVariables: { + ...lambdaDefaultEnvironmentVariables + }, + timeoutInSeconds: 30, + logRetentionInDays: props.logRetentionInDays, + logLevel: props.logLevel, + version: props.version, + commitId: props.commitId + }) + + this.functions = { + sandbox: sandboxLambda, + capabilityStatement: capabilityStatementLambda, + status: statusLambda + } + } +} From 41bf0e884f45b6b7cd6d2cc708709ab682786673 Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:32:33 +0000 Subject: [PATCH 21/22] feat: alarms --- packages/cdk/bin/PfPApiApp.ts | 1 + packages/cdk/constructs/MetricAlarm.ts | 70 ++++++++++++ packages/cdk/resources/Alarms.ts | 144 +++++++++++++++++++++++++ packages/cdk/stacks/PfPApiStack.ts | 8 ++ packages/cdk/tests/MetricAlarm.test.ts | 88 +++++++++++++++ packages/cdk/tests/synth.test.ts | 1 + 6 files changed, 312 insertions(+) create mode 100644 packages/cdk/constructs/MetricAlarm.ts create mode 100644 packages/cdk/resources/Alarms.ts create mode 100644 packages/cdk/tests/MetricAlarm.test.ts diff --git a/packages/cdk/bin/PfPApiApp.ts b/packages/cdk/bin/PfPApiApp.ts index 35f92aa02..38b84359d 100644 --- a/packages/cdk/bin/PfPApiApp.ts +++ b/packages/cdk/bin/PfPApiApp.ts @@ -30,6 +30,7 @@ function main() { tc007NhsNumberValue: getConfigFromEnvVar("tc007NhsNumberValue", CDK_ENV_PREFIX, "not_in_use"), tc008NhsNumberValue: getConfigFromEnvVar("tc008NhsNumberValue", CDK_ENV_PREFIX, "not_in_use"), tc009NhsNumberValue: getConfigFromEnvVar("tc009NhsNumberValue", CDK_ENV_PREFIX, "not_in_use"), + enableAlerts: getBooleanConfigFromEnvVar("enableAlerts", CDK_ENV_PREFIX, "true"), mutualTlsTrustStoreKey: props.isPullRequest ? undefined : getConfigFromEnvVar("trustStoreFile"), // CSOC API GW log destination - do not change csocApiGatewayDestination: "arn:aws:logs:eu-west-2:693466633220:destination:api_gateway_log_destination", diff --git a/packages/cdk/constructs/MetricAlarm.ts b/packages/cdk/constructs/MetricAlarm.ts new file mode 100644 index 000000000..dd44ddded --- /dev/null +++ b/packages/cdk/constructs/MetricAlarm.ts @@ -0,0 +1,70 @@ +import {Duration} from "aws-cdk-lib" +import {Construct} from "constructs" +import { + Alarm, + ComparisonOperator, + Metric, + TreatMissingData, + Unit +} from "aws-cdk-lib/aws-cloudwatch" +import {ITopic} from "aws-cdk-lib/aws-sns" + +type AlarmDefinition = { + name: string + metric: string + description: string + dimensions?: {[key: string]: string} + threshold?: number + comparisonOperator?: ComparisonOperator + unit?: Unit +} + +export interface MetricAlarmProps { + readonly stackName: string + readonly enableAlerts: boolean + readonly namespace: string + readonly alarmDefinition: AlarmDefinition + readonly slackAlertTopic: ITopic +} + +export class MetricAlarm extends Construct { + alarms: {[key: string]: Alarm} + + public constructor(scope: Construct, id: string, props: MetricAlarmProps){ + super(scope, id) + + const metricFunction = (metricName: string) => + new Metric({ + namespace: props.namespace, + metricName, + dimensionsMap: props.alarmDefinition.dimensions, + unit: props.alarmDefinition.unit ?? Unit.COUNT, + statistic: "Sum", + period: Duration.minutes(1) + }) + + const alarm = new Alarm(this, `${props.alarmDefinition.name}Alarm`, { + alarmName: `${props.stackName}-${props.alarmDefinition.name}`, + metric: metricFunction(props.alarmDefinition.metric), + threshold: props.alarmDefinition.threshold ?? 1, + evaluationPeriods: 1, + comparisonOperator: + props.alarmDefinition.comparisonOperator ?? ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, + treatMissingData: TreatMissingData.NOT_BREACHING, + alarmDescription: props.alarmDefinition.description, + actionsEnabled: props.enableAlerts + }) + + alarm.addAlarmAction({ + bind: () => ({alarmActionArn: props.slackAlertTopic.topicArn}) + }) + alarm.addOkAction({ + bind: () => ({alarmActionArn: props.slackAlertTopic.topicArn}) + }) + alarm.addInsufficientDataAction({ + bind: () => ({alarmActionArn: props.slackAlertTopic.topicArn}) + }) + + this.alarms = {[props.alarmDefinition.name]: alarm} + } +} diff --git a/packages/cdk/resources/Alarms.ts b/packages/cdk/resources/Alarms.ts new file mode 100644 index 000000000..5e08b6781 --- /dev/null +++ b/packages/cdk/resources/Alarms.ts @@ -0,0 +1,144 @@ +import {Fn} from "aws-cdk-lib" +import {Unit} from "aws-cdk-lib/aws-cloudwatch" +import { + MetricFilter, + FilterPattern, + IFilterPattern, + ILogGroup +} from "aws-cdk-lib/aws-logs" +import {Topic} from "aws-cdk-lib/aws-sns" +import {TypescriptLambdaFunction} from "@nhsdigital/eps-cdk-constructs" +import {Construct} from "constructs" +import {MetricAlarm} from "../constructs/MetricAlarm" + +export interface AlarmsProps { + readonly stackName: string + readonly enableAlerts: boolean + readonly functions: {[key: string]: TypescriptLambdaFunction} +} + +export class Alarms extends Construct { + public constructor(scope: Construct, id: string, props: AlarmsProps) { + super(scope, id) + + const createMetricFilter = ( + metricFilterId: string, + metricFilterProps: { + filterName: string + filterPattern: IFilterPattern + logGroup: ILogGroup + metricNamespace: string + metricName?: string + metricValue?: string + unit?: Unit + dimensions?: {[key: string]: string} + } + ) => new MetricFilter(this, metricFilterId, { + ...metricFilterProps, + metricName: metricFilterProps.metricName ?? "ErrorCount", + metricValue: metricFilterProps.metricValue ?? "1", + unit: metricFilterProps.unit ?? Unit.COUNT + }) + + const slackAlertTopic = Topic.fromTopicArn( + this, + "SlackAlertsTopic", + Fn.importValue("lambda-resources:SlackAlertsSnsTopicArn") + ) + + const getMyPrescriptionsFunction = props.functions.getMyPrescriptions.function + const enrichPrescriptionsFunction = props.functions.enrichPrescriptions.function + + createMetricFilter("ServiceSearchErrorsLogsMetricFilter", { + filterName: "ServiceSearchErrors", + filterPattern: FilterPattern.literal( + `{ ($.level = "ERROR") && ($.function_name = "${getMyPrescriptionsFunction.functionName}") ` + + "&& $.message = %error in request to serviceSearch% }" + ), + logGroup: getMyPrescriptionsFunction.logGroup, + metricNamespace: "LambdaLogFilterMetrics", + metricName: "ServiceSearchErrorCount", + dimensions: { + FunctionName: "$.function_name" + } + }) + + new MetricAlarm(this, "ServiceSearchErrors", { + stackName: props.stackName, + enableAlerts: props.enableAlerts, + namespace: "LambdaLogFilterMetrics", + alarmDefinition: { + name: "ServiceSearch_Errors", + metric: "ServiceSearchErrorCount", + description: "Count of Service Search errors", + dimensions: { + FunctionName: getMyPrescriptionsFunction.functionName + } + }, + slackAlertTopic + }) + + new MetricAlarm(this, "ServiceSearchUnhandledErrors", { + stackName: props.stackName, + enableAlerts: props.enableAlerts, + namespace: "Lambda", + alarmDefinition: { + name: "ServiceSearch_UnhandledErrors", + metric: "Errors", + description: "Count of Service Search unhandled errors", + dimensions: { + FunctionName: getMyPrescriptionsFunction.functionName + } + }, + slackAlertTopic + }) + + createMetricFilter("GetMyPrescriptionsErrorsLogsMetricFilter", { + filterName: `${props.stackName}_GetMyPrescriptionsErrors`, + filterPattern: FilterPattern.literal( + `{ ($.level = "ERROR") && ($.function_name = "${getMyPrescriptionsFunction.functionName}") ` + + "&& ($.message != %error in request to serviceSearch%) }" + ), + logGroup: getMyPrescriptionsFunction.logGroup, + metricNamespace: "LambdaLogFilterMetrics", + dimensions: { + FunctionName: "$.function_name" + } + }) + + new MetricAlarm(this, "GetMyPrescriptionsErrors", { + stackName: props.stackName, + enableAlerts: props.enableAlerts, + namespace: "LambdaLogFilterMetrics", + alarmDefinition: { + name: "GetMyPrescriptions_Errors", + metric: "ErrorCount", + description: "Count of GetMyPrescriptions errors", + dimensions: { + FunctionName: getMyPrescriptionsFunction.functionName + } + }, + slackAlertTopic + }) + + createMetricFilter("EnrichPrescriptionsErrorsLogsMetricFilter", { + filterName: `${props.stackName}_EnrichPrescriptionsErrors`, + filterPattern: FilterPattern.literal("ERROR"), + logGroup: enrichPrescriptionsFunction.logGroup, + metricNamespace: "LambdaLogFilterMetrics", + metricName: `${props.stackName}EnrichPrescriptionsErrorCount` + }) + + new MetricAlarm(this, "EnrichPrescriptionsErrors", { + stackName: props.stackName, + enableAlerts: props.enableAlerts, + namespace: "LambdaLogFilterMetrics", + alarmDefinition: { + name: "EnrichPrescriptions_Errors", + metric: `${props.stackName}EnrichPrescriptionsErrorCount`, + description: "Count of EnrichPrescriptions errors" + }, + slackAlertTopic + }) + } +} diff --git a/packages/cdk/stacks/PfPApiStack.ts b/packages/cdk/stacks/PfPApiStack.ts index b5493195d..f0da1651d 100644 --- a/packages/cdk/stacks/PfPApiStack.ts +++ b/packages/cdk/stacks/PfPApiStack.ts @@ -3,6 +3,7 @@ import {nagSuppressions} from "../nagSuppressions" import {Functions} from "../resources/Functions" import {StateMachines} from "../resources/StateMachines" import {Apis} from "../resources/Apis" +import {Alarms} from "../resources/Alarms" import {StandardStackProps} from "@nhsdigital/eps-cdk-constructs" import Parameters from "../resources/Parameters" @@ -19,6 +20,7 @@ export interface PfPApiStackProps extends StandardStackProps { readonly tc008NhsNumberValue: string readonly tc009NhsNumberValue: string readonly mutualTlsTrustStoreKey: string | undefined + readonly enableAlerts: boolean readonly csocApiGatewayDestination: string readonly forwardCsocLogs: boolean } @@ -56,6 +58,12 @@ export class PfPApiStack extends Stack { functions: functions.functions }) + new Alarms(this, "Alarms", { + stackName: props.stackName, + enableAlerts: props.enableAlerts, + functions: functions.functions + }) + new Apis(this, "Apis", { stackName: props.stackName, logRetentionInDays: props.logRetentionInDays, diff --git a/packages/cdk/tests/MetricAlarm.test.ts b/packages/cdk/tests/MetricAlarm.test.ts new file mode 100644 index 000000000..4550ccd25 --- /dev/null +++ b/packages/cdk/tests/MetricAlarm.test.ts @@ -0,0 +1,88 @@ +import {App, Stack} from "aws-cdk-lib" +import {Template} from "aws-cdk-lib/assertions" +import {ComparisonOperator, Unit} from "aws-cdk-lib/aws-cloudwatch" +import {Topic} from "aws-cdk-lib/aws-sns" +import {describe, expect, it} from "vitest" +import {MetricAlarm} from "../constructs/MetricAlarm" + +describe("MetricAlarm construct", () => { + it("applies sane defaults for simple alarm definitions", () => { + const app = new App() + const stack = new Stack(app, "TestStack") + const slackAlertTopic = new Topic(stack, "SlackAlertsTopic") + + new MetricAlarm(stack, "SimpleMetricAlarm", { + stackName: "pfp-test-stack", + enableAlerts: true, + namespace: "LambdaLogFilterMetrics", + alarmDefinition: { + name: "MySimpleAlarm", + metric: "ErrorCount", + description: "Simple alarm" + }, + slackAlertTopic + }) + + const template = Template.fromStack(stack) + + template.hasResourceProperties("AWS::CloudWatch::Alarm", { + AlarmName: "pfp-test-stack-MySimpleAlarm", + Namespace: "LambdaLogFilterMetrics", + MetricName: "ErrorCount", + Threshold: 1, + ComparisonOperator: "GreaterThanOrEqualToThreshold", + Unit: "Count", + Statistic: "Sum", + Period: 60, + EvaluationPeriods: 1, + TreatMissingData: "notBreaching", + AlarmDescription: "Simple alarm", + ActionsEnabled: true + }) + }) + + it("allows overriding threshold, comparison operator, unit and dimensions", () => { + const app = new App() + const stack = new Stack(app, "OverrideStack") + const slackAlertTopic = new Topic(stack, "SlackAlertsTopic") + + const metricAlarm = new MetricAlarm(stack, "OverrideMetricAlarm", { + stackName: "pfp-test-stack", + enableAlerts: false, + namespace: "CustomNamespace", + alarmDefinition: { + name: "MyOverrideAlarm", + metric: "Latency", + description: "Override alarm", + dimensions: { + FunctionName: "my-function" + }, + threshold: 250, + comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD, + unit: Unit.MILLISECONDS + }, + slackAlertTopic + }) + + expect(metricAlarm.alarms.MyOverrideAlarm).toBeDefined() + + const template = Template.fromStack(stack) + + template.hasResourceProperties("AWS::CloudWatch::Alarm", { + AlarmName: "pfp-test-stack-MyOverrideAlarm", + Namespace: "CustomNamespace", + MetricName: "Latency", + Threshold: 250, + ComparisonOperator: "GreaterThanThreshold", + Unit: "Milliseconds", + Dimensions: [ + { + Name: "FunctionName", + Value: "my-function" + } + ], + AlarmDescription: "Override alarm", + ActionsEnabled: false + }) + }) +}) diff --git a/packages/cdk/tests/synth.test.ts b/packages/cdk/tests/synth.test.ts index 208bd92cc..5585182bc 100644 --- a/packages/cdk/tests/synth.test.ts +++ b/packages/cdk/tests/synth.test.ts @@ -53,6 +53,7 @@ describe("CDK synth smoke tests", () => { CDK_CONFIG_tc007NhsNumberValue: "9000000009", CDK_CONFIG_tc008NhsNumberValue: "9000000017", CDK_CONFIG_tc009NhsNumberValue: "9000000025", + CDK_CONFIG_enableAlerts: "true", CDK_CONFIG_forwardCsocLogs: "false" } }) From 7e92406c9488283e5adccd0b5a58a78720b3849f Mon Sep 17 00:00:00 2001 From: tstephen-nhs <231503406+tstephen-nhs@users.noreply.github.com> Date: Thu, 2 Apr 2026 16:36:11 +0000 Subject: [PATCH 22/22] ops: tmp add cdk-utils tarball --- nhsdigital-eps-cdk-constructs-1.6.0.tgz | Bin 0 -> 247494 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 nhsdigital-eps-cdk-constructs-1.6.0.tgz diff --git a/nhsdigital-eps-cdk-constructs-1.6.0.tgz b/nhsdigital-eps-cdk-constructs-1.6.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..b920493d861853f786265a469eb809ca99bd66ea GIT binary patch literal 247494 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%0A`UEd|M$ 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 hGrpcdlf#|%cZzMG6p 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
OuUd>y=A=3#cK{j}zG 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

8#;Iw>b|Sss*2!Q)^v4+U^wG+6jIWS$kuD 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 Xb;Ndmdw+Ks(JuaY3u}fFi|GFVW);&b literal 0 HcmV?d00001