diff --git a/.github/actions/lint-and-validate-specification/action.yaml b/.github/actions/lint-and-validate-specification/action.yaml index d7f024d..5aa837b 100644 --- a/.github/actions/lint-and-validate-specification/action.yaml +++ b/.github/actions/lint-and-validate-specification/action.yaml @@ -31,8 +31,9 @@ runs: - name: Lint OpenAPI Spec with Spectral shell: bash - run: spectral lint --ruleset .spectral.yaml build/specification/eligibility-signposting-api.yaml + run: | + spectral lint --ruleset .spectral.yaml build/specification/${{ inputs.apim-env }}/eligibility-signposting-api.yaml - name: Validate OpenAPI Spec with Swagger CLI shell: bash - run: swagger-cli validate build/specification/eligibility-signposting-api.yaml + run: swagger-cli validate build/specification/${{ inputs.apim-env }}/eligibility-signposting-api.yaml diff --git a/.gitignore b/.gitignore index 956fd57..ce7ba36 100644 --- a/.gitignore +++ b/.gitignore @@ -20,9 +20,9 @@ public/ sandbox/tests sandbox/__pycache__ /specification/tmp/* +/specification/tmp/working/* /sandbox/specification/* sandbox/specification/* -/specification/postman /coverage.xml */package-lock.json diff --git a/.tool-versions b/.tool-versions index b94e252..81c3635 100644 --- a/.tool-versions +++ b/.tool-versions @@ -2,6 +2,7 @@ pre-commit 3.6.0 vale 3.6.0 +poetry 2.1.1 # ============================================================================== # The section below is reserved for Docker image versions. @@ -14,6 +15,7 @@ vale 3.6.0 # docker/ghcr.io/make-ops-tools/gocloc latest@sha256:6888e62e9ae693c4ebcfed9f1d86c70fd083868acb8815fe44b561b9a73b5032 # SEE: https://github.com/make-ops-tools/gocloc/pkgs/container/gocloc # docker/ghcr.io/nhs-england-tools/github-runner-image 20230909-321fd1e-rt@sha256:ce4fd6035dc450a50d3cbafb4986d60e77cb49a71ab60a053bb1b9518139a646 # SEE: https://github.com/nhs-england-tools/github-runner-image/pkgs/container/github-runner-image # docker/hadolint/hadolint 2.12.0-alpine@sha256:7dba9a9f1a0350f6d021fb2f6f88900998a4fb0aaf8e4330aa8c38544f04db42 # SEE: https://hub.docker.com/r/hadolint/hadolint/tags +# docker/hashicorp/terraform 1.5.6@sha256:180a7efa983386a27b43657ed610e9deed9e6c3848d54f9ea9b6cb8a5c8c25f5 # SEE: https://hub.docker.com/r/hashicorp/terraform/tags # docker/jdkato/vale v3.6.0@sha256:0ef22c8d537f079633cfff69fc46f69a2196072f69cab1ab232e8a79a388e425 # SEE: https://hub.docker.com/r/jdkato/vale/tags # docker/koalaman/shellcheck latest@sha256:e40388688bae0fcffdddb7e4dea49b900c18933b452add0930654b2dea3e7d5c # SEE: https://hub.docker.com/r/koalaman/shellcheck/tags # docker/mstruebing/editorconfig-checker 2.7.1@sha256:dd3ca9ea50ef4518efe9be018d669ef9cf937f6bb5cfe2ef84ff2a620b5ddc24 # SEE: https://hub.docker.com/r/mstruebing/editorconfig-checker/tags diff --git a/Makefile b/Makefile index ea39160..4a32978 100644 --- a/Makefile +++ b/Makefile @@ -7,16 +7,12 @@ MAKE_DIR := $(abspath $(shell pwd)) #Installs dependencies using poetry. install-python: - poetry install + poetry install --no-root #Installs dependencies using npm. install-node: npm install --legacy-peer-deps -#Configures Git Hooks, which are scripts that run given a specified event. -.git/hooks/pre-commit: - cp scripts/pre-commit .git/hooks/pre-commit - #Condensed Target to run all targets above. install: install-node install-python .git/hooks/pre-commit @@ -33,11 +29,12 @@ format: ## Format and fix code poetry run ruff check . --fix-only #Creates the fully expanded OAS spec in json -publish: clean +generate-sandbox-spec: clean mkdir -p build mkdir -p sandbox/specification npm run publish 2> /dev/null - cp build/eligibility-signposting-api.json sandbox/specification/eligibility-signposting-api.json + cp build/specification/sandbox/eligibility-signposting-api.json sandbox/specification/eligibility-signposting-api.json + #Files to loop over in release _dist_include="pytest.ini poetry.lock poetry.toml pyproject.toml Makefile build/. tests" @@ -66,6 +63,26 @@ get-spec: # Get the most recent specification live in proxygen $(MAKE) setup-proxygen-credentials proxygen spec get +get-spec-uat: # Get the most recent specification live in proxygen + $(MAKE) setup-proxygen-credentials + proxygen spec get --uat + +publish-spec: # Publish the specification to proxygen + $(MAKE) setup-proxygen-credentials + proxygen spec publish --specification-file build/prod/eligibility-signposting-api.yaml + +publish-spec-uat: # Publish the specification to proxygen + $(MAKE) setup-proxygen-credentials + proxygen spec publish --specification-file build/preprod/eligibility-signposting-api.yaml --uat + +delete-spec: # Delete the specification from proxygen + $(MAKE) setup-proxygen-credentials + proxygen spec delete + +delete-spec-uat: # Delete the specification from proxygen + $(MAKE) setup-proxygen-credentials + proxygen spec delete --uat + # Specification guard-%: @@ -107,9 +124,12 @@ endif construct-spec: guard-APIM_ENV @ $(MAKE) update-spec-template APIM_ENV=$$APIM_ENV - mkdir -p build/specification && \ + mkdir -p build/specification/$(APIM_ENV) && \ npx redocly bundle specification/eligibility-signposting-api.yaml --remove-unused-components --keep-url-references --ext yaml \ - > build/specification/eligibility-signposting-api.yaml + > build/specification/$(APIM_ENV)/eligibility-signposting-api.yaml +ifeq ($(APIM_ENV),sandbox) + yq 'del(.components.securitySchemes)' build/specification/sandbox/eligibility-signposting-api.yaml > build/specification/sandbox/eligibility-signposting-api.yaml.tmp && mv build/specification/sandbox/eligibility-signposting-api.yaml.tmp build/specification/sandbox/eligibility-signposting-api.yaml +endif SPEC_DIR := $(CURDIR)/specification POSTMAN_DIR := $(SPEC_DIR)/postman @@ -118,8 +138,9 @@ convert-postman: # Create Postman collection from OAS spec mkdir -p $(POSTMAN_DIR) cp $(SPEC_DIR)/eligibility-signposting-api.yaml $(POSTMAN_DIR)/ docker build -t portman-converter -f $(POSTMAN_DIR)/Dockerfile $(SPEC_DIR) - docker run --rm -v $(SPEC_DIR):/app portman-converter \ + docker run --rm -u $(shell id -u):$(shell id -g) -v $(SPEC_DIR):/app portman-converter \ portman -l /app/eligibility-signposting-api.yaml -o /app/postman/collection.json + echo >> $(POSTMAN_DIR)/collection.json rm $(POSTMAN_DIR)/eligibility-signposting-api.yaml # ============================================================================== diff --git a/package.json b/package.json index f087ac4..3bcfcb3 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "OAS (Swagger v3) API Definition for Template API", "scripts": { "lint": "node_modules/.bin/openapi-generator-cli validate -i specification/eligibility-signposting-api.yaml", - "publish": "./node_modules/.bin/openapi-generator-cli generate -i build/specification/eligibility-signposting-api.yaml --generator-key v3.0 -g openapi -o build && rm openapitools.json && mv build/openapi.json build/eligibility-signposting-api.json", + "publish": "./node_modules/.bin/openapi-generator-cli generate -i build/specification/sandbox/eligibility-signposting-api.yaml --generator-key v3.0 -g openapi -o build && rm openapitools.json && mv build/openapi.json build/specification/sandbox/eligibility-signposting-api.json", "check-licenses": "node_modules/.bin/license-checker --failOn GPL --failOn LGPL" }, "author": "NHS Digital", diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..bff692b --- /dev/null +++ b/poetry.lock @@ -0,0 +1,377 @@ +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. + +[[package]] +name = "argcomplete" +version = "3.6.2" +description = "Bash tab completion for argparse" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591"}, + {file = "argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf"}, +] + +[package.extras] +test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] + +[[package]] +name = "awscli" +version = "1.40.4" +description = "Universal Command Line Environment for AWS." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "awscli-1.40.4-py3-none-any.whl", hash = "sha256:1e2458bfbbb84600eff5ef66bf1660d0e1ead1cd0075fbe4366a4e8151e0fc82"}, + {file = "awscli-1.40.4.tar.gz", hash = "sha256:ee22453a9ade6f3a2bbf20e88c49a40a5655eb208d7e8945b6e614871b49a9b7"}, +] + +[package.dependencies] +botocore = "1.38.5" +colorama = ">=0.2.5,<0.4.7" +docutils = ">=0.18.1,<=0.19" +PyYAML = ">=3.10,<6.1" +rsa = ">=3.1.2,<4.8" +s3transfer = ">=0.12.0,<0.13.0" + +[[package]] +name = "awscli-local" +version = "0.22.0" +description = "Thin wrapper around the \"aws\" command line interface for use with LocalStack" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "awscli-local-0.22.0.tar.gz", hash = "sha256:3807cf2ee4bbdd4df4dfc8bef027f25bde523dcaf8119720f677ed95ebba66a4"}, +] + +[package.dependencies] +localstack-client = "*" + +[package.extras] +ver1 = ["awscli"] + +[[package]] +name = "boto3" +version = "1.38.5" +description = "The AWS SDK for Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "boto3-1.38.5-py3-none-any.whl", hash = "sha256:78601ef259865a954ae0385f278fbe5d9b632cf6c5fe6500e1ceb94d35acf07f"}, + {file = "boto3-1.38.5.tar.gz", hash = "sha256:4cd581f77e67dbc28579134e1ee7b522797cfde30e0c735e7537ec4a3fb6af45"}, +] + +[package.dependencies] +botocore = ">=1.38.5,<1.39.0" +jmespath = ">=0.7.1,<2.0.0" +s3transfer = ">=0.12.0,<0.13.0" + +[package.extras] +crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] + +[[package]] +name = "botocore" +version = "1.38.5" +description = "Low-level, data-driven core of boto 3." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "botocore-1.38.5-py3-none-any.whl", hash = "sha256:df1dc1dfe3607e3f802ddeb1f25a9f0abc8909ea674032480f71362e96c3c548"}, + {file = "botocore-1.38.5.tar.gz", hash = "sha256:506e8274f7ddb84ca4ec85f7f9229de59fb43702e2e0b1400bea07f7f4a7ba82"}, +] + +[package.dependencies] +jmespath = ">=0.7.1,<2.0.0" +python-dateutil = ">=2.1,<3.0.0" +urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} + +[package.extras] +crt = ["awscrt (==0.23.8)"] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["dev"] +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "docutils" +version = "0.19" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, + {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, +] + +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] + +[[package]] +name = "localstack-client" +version = "2.10" +description = "A lightweight Python client for LocalStack." +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "localstack_client-2.10.tar.gz", hash = "sha256:732a07e23fffd6a581af2714bbe006ad6f884ac4f8ac955211a8a63321cdc409"}, +] + +[package.dependencies] +boto3 = "*" + +[package.extras] +test = ["black", "coverage", "flake8", "isort", "localstack", "pytest"] + +[[package]] +name = "pyasn1" +version = "0.4.8" +description = "ASN.1 types and codecs" +optional = false +python-versions = "*" +groups = ["dev"] +files = [ + {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["dev"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "rsa" +version = "4.7.2" +description = "Pure-Python RSA implementation" +optional = false +python-versions = ">=3.5, <4" +groups = ["dev"] +files = [ + {file = "rsa-4.7.2-py3-none-any.whl", hash = "sha256:78f9a9bf4e7be0c5ded4583326e7461e3a3c5aae24073648b4bdfa797d78c9d2"}, + {file = "rsa-4.7.2.tar.gz", hash = "sha256:9d689e6ca1b3038bc82bf8d23e944b6b6037bc02301a574935b2dd946e0353b9"}, +] + +[package.dependencies] +pyasn1 = ">=0.1.3" + +[[package]] +name = "ruff" +version = "0.11.7" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "ruff-0.11.7-py3-none-linux_armv6l.whl", hash = "sha256:d29e909d9a8d02f928d72ab7837b5cbc450a5bdf578ab9ebee3263d0a525091c"}, + {file = "ruff-0.11.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:dd1fb86b168ae349fb01dd497d83537b2c5541fe0626e70c786427dd8363aaee"}, + {file = "ruff-0.11.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d3d7d2e140a6fbbc09033bce65bd7ea29d6a0adeb90b8430262fbacd58c38ada"}, + {file = "ruff-0.11.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4809df77de390a1c2077d9b7945d82f44b95d19ceccf0c287c56e4dc9b91ca64"}, + {file = "ruff-0.11.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f3a0c2e169e6b545f8e2dba185eabbd9db4f08880032e75aa0e285a6d3f48201"}, + {file = "ruff-0.11.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49b888200a320dd96a68e86736cf531d6afba03e4f6cf098401406a257fcf3d6"}, + {file = "ruff-0.11.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2b19cdb9cf7dae00d5ee2e7c013540cdc3b31c4f281f1dacb5a799d610e90db4"}, + {file = "ruff-0.11.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64e0ee994c9e326b43539d133a36a455dbaab477bc84fe7bfbd528abe2f05c1e"}, + {file = "ruff-0.11.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bad82052311479a5865f52c76ecee5d468a58ba44fb23ee15079f17dd4c8fd63"}, + {file = "ruff-0.11.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7940665e74e7b65d427b82bffc1e46710ec7f30d58b4b2d5016e3f0321436502"}, + {file = "ruff-0.11.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:169027e31c52c0e36c44ae9a9c7db35e505fee0b39f8d9fca7274a6305295a92"}, + {file = "ruff-0.11.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:305b93f9798aee582e91e34437810439acb28b5fc1fee6b8205c78c806845a94"}, + {file = "ruff-0.11.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a681db041ef55550c371f9cd52a3cf17a0da4c75d6bd691092dfc38170ebc4b6"}, + {file = "ruff-0.11.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:07f1496ad00a4a139f4de220b0c97da6d4c85e0e4aa9b2624167b7d4d44fd6b6"}, + {file = "ruff-0.11.7-py3-none-win32.whl", hash = "sha256:f25dfb853ad217e6e5f1924ae8a5b3f6709051a13e9dad18690de6c8ff299e26"}, + {file = "ruff-0.11.7-py3-none-win_amd64.whl", hash = "sha256:0a931d85959ceb77e92aea4bbedfded0a31534ce191252721128f77e5ae1f98a"}, + {file = "ruff-0.11.7-py3-none-win_arm64.whl", hash = "sha256:778c1e5d6f9e91034142dfd06110534ca13220bfaad5c3735f6cb844654f6177"}, + {file = "ruff-0.11.7.tar.gz", hash = "sha256:655089ad3224070736dc32844fde783454f8558e71f501cb207485fe4eee23d4"}, +] + +[[package]] +name = "s3transfer" +version = "0.12.0" +description = "An Amazon S3 Transfer Manager" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "s3transfer-0.12.0-py3-none-any.whl", hash = "sha256:35b314d7d82865756edab59f7baebc6b477189e6ab4c53050e28c1de4d9cce18"}, + {file = "s3transfer-0.12.0.tar.gz", hash = "sha256:8ac58bc1989a3fdb7c7f3ee0918a66b160d038a147c7b5db1500930a607e9a1c"}, +] + +[package.dependencies] +botocore = ">=1.37.4,<2.0a.0" + +[package.extras] +crt = ["botocore[crt] (>=1.37.4,<2.0a.0)"] + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["dev"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "tomlkit" +version = "0.13.2" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, +] + +[[package]] +name = "urllib3" +version = "2.4.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"}, + {file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "xmltodict" +version = "0.14.2" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.6" +groups = ["main", "dev"] +files = [ + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, +] + +[[package]] +name = "yq" +version = "3.4.3" +description = "Command-line YAML/XML processor - jq wrapper for YAML/XML documents" +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "yq-3.4.3-py3-none-any.whl", hash = "sha256:547e34bc3caacce83665fd3429bf7c85f8e8b6b9aaee3f953db1ad716ff3434d"}, + {file = "yq-3.4.3.tar.gz", hash = "sha256:ba586a1a6f30cf705b2f92206712df2281cd320280210e7b7b80adcb8f256e3b"}, +] + +[package.dependencies] +argcomplete = ">=1.8.1" +PyYAML = ">=5.3.1" +tomlkit = ">=0.11.6" +xmltodict = ">=0.11.0" + +[package.extras] +tests = ["build", "coverage", "mypy", "ruff", "wheel"] + +[metadata] +lock-version = "2.1" +python-versions = "^3.13" +content-hash = "d7ba1f53a544b0ca73d6717e208c3c148824ebaec39e7f0bccdcd3db3841269b" diff --git a/poetry.toml b/poetry.toml new file mode 100644 index 0000000..ab1033b --- /dev/null +++ b/poetry.toml @@ -0,0 +1,2 @@ +[virtualenvs] +in-project = true diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3b60c52 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,62 @@ +[project] +name = "eligibility-signposting-api-specification" +version = "0.0.1-alpha" +description = "TODO" +authors = [ + #TODO add authors +] +readme = "README.md" +requires-python = ">=3.13" +repository = "https://github.com/NHSDigital/eligibility-signposting-api-specification" +homepage = "https://digital.nhs.uk/developer/api-catalogue" +keywords = ["healthcare", "uk", "nhs", "vaccination", "api"] #TODO add additional keywords +package_mode = false + +[build-system] +requires = ["poetry-core>=2.0.0,<3.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.dependencies] +python = "^3.13" +yq = "^3.2.3" + +[tool.poetry.group.dev.dependencies] +ruff = "^0.11.0" +awscli = "^1.37.24" +awscli-local = "^0.22.0" +yq = "^3.2.3" # Development-only dependency for YAML processing; version chosen for compatibility with project tooling + +[tool.ruff] +line-length = 120 +exclude = ["docs/", "scripts/"] + +[tool.ruff.lint] +select = ["ALL"] +ignore = ["COM812", "D"] + +[tool.ruff.lint.per-file-ignores] +"src/eligibility_signposting_api/repos/*" = ["ANN401"] +"tests/*" = ["ANN", "INP", "S101", "S106"] + +[tool.pytest.ini_options] +log_cli = true +log_cli_level = "DEBUG" +log_format = "%(asctime)s %(levelname)s %(message)s" +log_date_format = "%Y-%m-%d %H:%M:%S" +asyncio_mode = "auto" +asyncio_default_fixture_loop_scope = "function" + +[tool.coverage.run] +relative_files = true +branch = true +source = ["sandbox"] + +[tool.coverage.report] +show_missing = true +skip_covered = false +exclude_lines = [ + "pragma: no cover", + "if __name__ == .__main__.:", + "if TYPE_CHECKING:", + "raise NotImplementedError", +] diff --git a/sandbox/Makefile b/sandbox/Makefile index 637da37..26a086d 100644 --- a/sandbox/Makefile +++ b/sandbox/Makefile @@ -25,7 +25,7 @@ update: spec: mkdir -p specification - make -C .. publish + make -C .. generate-sandbox-spec test: UPSTREAM_HOST=test poetry run pytest diff --git a/sandbox/README.md b/sandbox/README.md index fba5fb1..be29788 100644 --- a/sandbox/README.md +++ b/sandbox/README.md @@ -28,7 +28,7 @@ This will stop the sandbox environment. There are a number of examples of responses which can be returned by passing specific NHS Numbers in the patient query parameter: ```bash - curl -X GET "http://0.0.0.0:9000/eligibility-check?patient=" -H "Authorization: Bearer sdvsd" + curl -X GET "http://0.0.0.0:9000/patient-check/ ``` #### Example scenarios diff --git a/sandbox/app.py b/sandbox/app.py index 2ddd399..369fc76 100644 --- a/sandbox/app.py +++ b/sandbox/app.py @@ -38,16 +38,16 @@ ] PATIENT_EXAMPLES = { - "patient=50000000001": "example_50000000001", - "patient=50000000002": "example_50000000002", - "patient=50000000003": "example_50000000003", - "patient=50000000004": "example_50000000004", - "patient=50000000005": "example_50000000005", - "patient=50000000006": "example_50000000006", - "patient=90000000400": "code400", - "patient=90000000404": "code404", - "patient=90000000422": "code422", - "patient=90000000500": "code500", + "patient-check/50000000001": "example_50000000001", + "patient-check/50000000002": "example_50000000002", + "patient-check/50000000003": "example_50000000003", + "patient-check/50000000004": "example_50000000004", + "patient-check/50000000005": "example_50000000005", + "patient-check/50000000006": "example_50000000006", + "patient-check/90000000400": "code400", + "patient-check/90000000404": "code404", + "patient-check/90000000422": "code422", + "patient-check/90000000500": "code500", } diff --git a/sandbox/poetry.lock b/sandbox/poetry.lock index cb477cd..6fe0253 100644 --- a/sandbox/poetry.lock +++ b/sandbox/poetry.lock @@ -1,5 +1,20 @@ # This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +[[package]] +name = "argcomplete" +version = "3.6.2" +description = "Bash tab completion for argparse" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591"}, + {file = "argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf"}, +] + +[package.extras] +test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] + [[package]] name = "blinker" version = "1.9.0" @@ -372,6 +387,69 @@ pluggy = ">=0.12,<2.0" [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + [[package]] name = "requests" version = "2.32.3" @@ -394,6 +472,18 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "tomlkit" +version = "0.13.2" +description = "Style preserving TOML library" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"}, + {file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"}, +] + [[package]] name = "urllib3" version = "2.3.0" @@ -430,7 +520,40 @@ MarkupSafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] +[[package]] +name = "xmltodict" +version = "0.14.2" +description = "Makes working with XML feel like you are working with JSON" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +files = [ + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, +] + +[[package]] +name = "yq" +version = "3.4.3" +description = "Command-line YAML/XML processor - jq wrapper for YAML/XML documents" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "yq-3.4.3-py3-none-any.whl", hash = "sha256:547e34bc3caacce83665fd3429bf7c85f8e8b6b9aaee3f953db1ad716ff3434d"}, + {file = "yq-3.4.3.tar.gz", hash = "sha256:ba586a1a6f30cf705b2f92206712df2281cd320280210e7b7b80adcb8f256e3b"}, +] + +[package.dependencies] +argcomplete = ">=1.8.1" +PyYAML = ">=5.3.1" +tomlkit = ">=0.11.6" +xmltodict = ">=0.11.0" + +[package.extras] +tests = ["build", "coverage", "mypy", "ruff", "wheel"] + [metadata] lock-version = "2.1" python-versions = ">=3.13" -content-hash = "be1bc3e9d5eb541f5a8fb709eb8e360e327cac4f2d445c4f3718e1423794b7b0" +content-hash = "d82c2dfac34b5c8ed294083dace28e846f9d22c55ba1a9d8894526ae811f3df4" diff --git a/sandbox/pyproject.toml b/sandbox/pyproject.toml index b1c9681..0341238 100644 --- a/sandbox/pyproject.toml +++ b/sandbox/pyproject.toml @@ -20,3 +20,4 @@ build-backend = "poetry.core.masonry.api" [tool.poetry.group.dev.dependencies] pytest = "^7.0" pyhamcrest = "^2.1.0" +yq = "^3.2.3" diff --git a/sandbox/specification/eligibility-signposting-api.json b/sandbox/specification/eligibility-signposting-api.json deleted file mode 100644 index 9f399f1..0000000 --- a/sandbox/specification/eligibility-signposting-api.json +++ /dev/null @@ -1,785 +0,0 @@ -{ - "openapi" : "3.0.1", - "info" : { - "contact" : { - "url" : "https://developer.nhs.uk/apis/eligibility-signposting-api" - }, - "description" : "## Overview\n Use this API to access the [Eligibility Signposting API](https://digital.nhs.uk/services/eligibility-signposting) - the nationally curated single source of eligibility status and signposted actions for individuals. For example, you can request eligibility for one or more vaccination types to understand if NHS England holds information which suggest that the person could or should take further steps toward receiving those vaccinations, and optionally, a list of the steps NHS England would recommend.\n \n Where someone is deemed eligible, they will also be classified as actionable or not actionable. When deemed not actionable, a reason will be returned. These reasons can range from personal care setting impacts to current lack of availability of vaccines and more.\n \n The API returns most of its data in both codes and text. Unless agreed with NHS England, where text is provided it should be displayed to the user as-is.\n \n This API currently has a single User Restricted access mode and will operate only in the context of the authenticated individual, you may however request:\n * eligibility for all supported vaccinations\n * eligibility for specified supported vaccinations\n * request that actions be included in the response\n * request that actions not be included in the response\n \n You cannot currently use this API to:\n * request eligibility for proxy people (familial relations etc.)\n * request actions for people considered ineligible\n \n This API is read-only and can return a list of processed suggestions, each relating to a 'condition' (e.g. COVID, RSV, BOWEL, EYE, BREAST etc.), including the following information for each:\n * a code representing the condition (COVID, RSV, BOWEL, EYE, BREAST)\n * an overall status (NotEligible, NotActionable, Actionable)\n * a list of eligibility cohort groups to which the person belongs (when eligible)\n * a list of the cohort groups that could have made the person eligible (when not eligible)\n * a list of rules/reasons that deem a person to be NotActionable\n * a list of actions that should be shown to the consumer\n \n #### Definitions of Overall Status \n \nThe overall status values indicate the following:\n \n* NotEligible - the individual does not currently meet eligibility criteria\n* NotActionable - the individual is eligible but does not need to take any further action at this time\n* Actionable - the individual is eligible and should follow one of the recommended actions provided\n \n### Patients included in the Eligibility Signposting API\n The API will return data for all patients who are in the NHS PDS system that are registered with an English GP practice (or one administered by England) or who we believe to be resident in England. \n \n Patients who are deceased (or thought to be), marked as invalid or sensitive will not be processed by this API.\n \n ## Who can use this API\n This API can only be used where there is a [legal basis](https://digital.nhs.uk/services/eligibility-signposting/legal-basis) to do so. Make sure you have a valid use case before you go too far with your development. You must demonstrate you have a [valid use case](https://digital.nhs.uk/services/eligibility-signposting/legal-basis) as part of digital onboarding. \n \n You must do this before you can go live (see 'Onboarding' below).\n \n ### Who can access Eligibility Signposting Information\n Patients who receive health and social care or make use of NHS services in England, Wales and the Isle of Man can access their own Eligibility Signposting data through onboarded services.\n \n Health and care organisations in England and the Isle of Man can access our information for legitimate direct care purposes. Legitimate direct care examples include NHS organisations delivering healthcare, local authorities delivering care, third sector and private sector health and care organisations, and developers delivering systems to health and care organisations. \n \n \n ### Existing API users\n To find out which healthcare software development organisations and products are already using this API, see [Eligibility Signposting API - integrated products](https://digital.nhs.uk/services/eligibility-signposting/integrated-products).\n \n ## Access modes\n This API currently has only one access mode:\n * patient access \n \n We are considering the possibility of adding other modes in the future:\n * healthcare worker access \n * restricted access \n \n ### Patient access \n If the end user is a patient then you must use this access mode. Use this access mode to obtain data for that patient.\n \n This access mode is [user-restricted](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation#user-restricted-apis), meaning an end user must be present, authenticated and authorised. \n \n The end user must be: \n * a patient who receives health and social care or makes use of NHS services \n * strongly authenticated, using [NHS login](https://digital.nhs.uk/services/nhs-login)\n \n To use this access mode, use one of the following security patterns:\n \n |\tSecurity pattern\t\t |\tTechnical details\t |\tAdvantages\t | Disadvantages |\n |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------------------------------------------------| ------------------------------------------------------------|---------------------------------------------------------|\n |[NHS login - combined authentication and authorisation](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/user-restricted-restful-apis-nhs-login-combined-authentication-and-authorisation) |OAuth 2.0 authorisation code with API key and secret |No need to integrate and onboard separately with NHS login. |No access to user information. |\n |[NHS login - separate authentication and authorisation](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/user-restricted-restful-apis-nhs-login-separate-authentication-and-authorisation) |OAuth 2.0 token exchange with signed JWT |Gives access to user information. |Need to integrate and onboard separately with NHS login. |\n \n Patient access mode users must be authenticated to a high proofing level (P9) and to one of the following [vectors of trust](https://nhsconnect.github.io/nhslogin/vectors-of-trust/): \n * P9.Cp.Cd\n * P9.Cp.Ck\n * P9.Cm\n \n This access mode is available in production ([beta](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#api-status)).\n \n ### Restricted access\n This access mode is not yet available, if you believe this mode would benefit your use-case, please let us know.\n \n This access mode is [application-restricted](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation#application-restricted-apis), meaning we authenticate and authorise the calling application but not the end user. \n \n This access mode is not designed to be accessed by an end user. You might use this access mode as part of a back-end process to: \n * retrieve eligibility signposting information into a system in advance of a clinic\n * retrieve eligibility signposting information into a system to be used in a disconnected manner\n \n To use this access mode, use this security pattern:\n * [Application-restricted RESTful API - signed JWT authentication](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/application-restricted-restful-apis-signed-jwt-authentication)\n \n ## Roadmap\n The [Eligibility Signposting API](https://digital.nhs.uk/services/eligibility-signposting/roadmap-and-strategy) roadmap shows the planned changes for the API. \n \n To see our roadmap, or to suggest, comment or vote on features for this API, see our [interactive product backlog](https://nhs-digital-api-management.featureupvote.com/suggestions/612352/eligibility-signposting-api-vaccinations).\n \n If you have any other queries, please [contact us](https://digital.nhs.uk/developer/help-and-support).\n \n ## Service level\n \n This API is a silver service, meaning it is operational 24 hours a day, 365 days a year and supported 8am to 6pm, Monday to Friday excluding bank holidays.\n \n For more details, see [service levels](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#service-levels).\n \n ## Rate limits\n \n The default rate limit is 25TPS (Transactions Per Second), per app. If you require a higher rate limit please [contact us](https://digital.nhs.uk/developer/help-and-support). or raise this during the onboarding process.\n \n ## Technology\n This API is [RESTful](https://digital.nhs.uk/developer/guides-and-documentation/our-api-technologies#basic-rest).\n \n ## Network access\n This API is available on the internet and, indirectly, on the [Health and Social Care Network (HSCN)](https://digital.nhs.uk/services/health-and-social-care-network).\n \n For more details see [Network access for APIs](https://digital.nhs.uk/developer/guides-and-documentation/network-access-for-apis).\n \n ## Errors\n We use standard HTTP status codes to show whether an API request succeeded or not. They are usually in the range:\n \n * 200 to 299 if it succeeded, including code 202 if it was accepted by an API that needs to wait for further action\n * 400 to 499 if it failed because of a client error by your application\n * 500 to 599 if it failed because of an error on our server\n \n Errors specific to each API are shown in the Endpoints section, under Response. See our [reference guide](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#http-status-codes) for more on errors.\n \n Your API-calling application should have a mechanism to automatically try again, for example by giving status information to your end user, before giving up. See our [reference guide](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#error-handling) for more information about error handling.\n \n ## Open source\n You might find the following [open source](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#open-source) resources useful:\n \n | Resource | Description | Links |\n |---------------------------|----------------------------------------------------------------------|--------------------------------------------------------------------------------|\n | Eligibility Signposting API| Source code including API proxy, sandbox and specification and code. | [GitHub repo](https://github.com/NHSDigital/eligibility-signposting-api) |\n \n We currently don't have any open source client libraries or sample code for this API. If you think this would be useful, you can [upvote the suggestion on our Interactive Product Backlog](https://nhs-digital-api-management.featureupvote.com/suggestions/107439/client-libraries-and-reference-implementations).\n \n \n \n ## Environments and testing\n \n | Environment | Base URL |\n | ----------------- | ---------------------------------------------------------------------- |\n | Sandbox | `https://sandbox.api.service.nhs.uk/eligibility-signposting/eligibility-check` |\n | Integration test | `https://int.api.service.nhs.uk/eligibility-signposting/eligibility-check` |\n | Production | `https://api.service.nhs.uk/eligibility-signposting/eligibility-check` |\n \n ### Sandbox testing\n Our [sandbox environment](https://digital.nhs.uk/developer/guides-and-documentation/testing#sandbox-testing):\n * is for early developer testing\n * only covers a limited set of scenarios\n * is open access, so does not allow you to test authorisation\n \n For details of sandbox test scenarios, or to try out the sandbox using our 'Try this API' feature, see the documentation for each endpoint.\n \n Alternatively, you can try out the sandbox using our Postman collection:\n \n [![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/?????????????????????????????????)\n \n ### Integration testing\n Our [integration test environment](https://digital.nhs.uk/developer/guides-and-documentation/testing#integration-testing):\n * is for formal integration testing\n * includes authorisation, with options for user-restricted access (NHS Login) \n ### Production smoke testing\n You must not use real patient data for smoke testing in the production environment.\n \n Rather, use our [production test patient](https://digital.nhs.uk/services/eligibility-signposting/api-test-data#production-smoke-testing).\n \n ## Onboarding\n You need to get your software approved by us before it can go live with this API. We call this onboarding. The onboarding process can sometimes be quite long, so it is worth planning well ahead.\n \n As part of this process, you need to demonstrate your technical conformance to the requirements for this API. \n \n You also need to demonstrate that you can manage risks. This might impact the design of your software. For details, see [Onboarding support information](https://digital.nhs.uk/services/eligibility-signposting/onboarding-support-information).\n \n To understand how our online digital onboarding process works, see [digital onboarding](https://digital.nhs.uk/developer/guides-and-documentation/digital-onboarding). \n \n \n ## Related APIs\n \n The following APIs are related to this API:\n\n", - "termsOfService" : "https://developer.nhs.uk/apis/eligibility-signposting-api", - "title" : "Eligibility Signposting API", - "version" : "1.0.8-alpha" - }, - "servers" : [ { - "description" : "Sandbox Server", - "url" : "https://sandbox.api.service.nhs.uk/eligibility-signposting" - }, { - "description" : "Integration Server", - "url" : "https://int.api.service.nhs.uk/eligibility-signposting" - }, { - "description" : "Production Server", - "url" : "https://api.service.nhs.uk/eligibility-signposting" - } ], - "tags" : [ { - "name" : "Eligibility" - }, { - "name" : "Signposting" - }, { - "name" : "NextActions" - } ], - "paths" : { - "/eligibility-check" : { - "get" : { - "description" : "Determines which suggestions a person is eligible for and which they are not, including reasons and next steps.", - "operationId" : "checkEligibility", - "parameters" : [ { - "description" : "The NHS number of the person.", - "explode" : true, - "in" : "query", - "name" : "patient", - "required" : true, - "schema" : { - "example" : "9876543210", - "type" : "string" - }, - "style" : "form" - }, { - "description" : "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", - "explode" : true, - "in" : "query", - "name" : "category", - "required" : false, - "schema" : { - "default" : "ALL", - "enum" : [ "VACCINATIONS", "SCREENING", "ALL" ], - "example" : "VACCINATIONS", - "type" : "string" - }, - "style" : "form" - }, { - "description" : "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", - "explode" : true, - "in" : "query", - "name" : "conditions", - "required" : false, - "schema" : { - "default" : "ALL", - "example" : "FLU,RSV", - "type" : "string" - }, - "style" : "form" - }, { - "description" : "When Y is passed in, the API will include one or more actions as applicable. Passing in N will result in no actions being calculated or returned.", - "explode" : true, - "in" : "query", - "name" : "includeActions", - "required" : false, - "schema" : { - "default" : "Y", - "enum" : [ "Y", "N" ], - "example" : "Y", - "type" : "string" - }, - "style" : "form" - } ], - "responses" : { - "200" : { - "content" : { - "application/json" : { - "examples" : { - "example_50000000001" : { - "summary" : "RSV - Actionable CP Booking", - "value" : { - "responseId" : "1a233ba5-e1eb-4080-a086-2962f6fc3473", - "meta" : { - "lastUpdated" : "2025-02-12T16:11:22Z" - }, - "processedSuggestions" : [ { - "condition" : "RSV", - "status" : "Actionable", - "statusText" : "Actionable - Individual is eligible and we suggest that they follow one or more of the provided actions", - "eligibilityCohorts" : [ { - "cohortCode" : "rsv_75-79_ongoing", - "cohortText" : "You're aged 75 to 79", - "cohortStatus" : "Actionable" - } ], - "actions" : [ { - "actionType" : "PrimaryButton", - "actionCode" : "NationalCPBook", - "description" : "Book or Amend an RSV vaccinations appointment", - "urlLink" : "http://www.nhs.uk/book-rsv" - }, { - "actionType" : "InfoText", - "actionCode" : "AwaitGPContact", - "description" : "You can wait for your GP surgery to contact you about getting the RSV vaccine. This may be by letter, text, phone call or email." - } ] - } ] - } - }, - "example_50000000002" : { - "summary" : "RSV - Actionable Not CP Booking", - "value" : { - "responseId" : "1a233ba5-e1eb-4080-a086-2962f6fc3002", - "meta" : { - "lastUpdated" : "2025-02-12T16:11:22Z" - }, - "processedSuggestions" : [ { - "condition" : "RSV", - "status" : "Actionable", - "statusText" : "Actionable - Individual is eligible and we suggest that they follow one or more of the provided actions", - "eligibilityCohorts" : [ { - "cohortCode" : "rsv_75-79_ongoing", - "cohortText" : "You're aged 75 to 79", - "cohortStatus" : "Actionable" - } ], - "actions" : [ { - "actionType" : "InfoText", - "actionCode" : "AwaitGPContact", - "description" : "You can wait for your GP surgery to contact you about getting the RSV vaccine. This may be by letter, text, phone call or email." - }, { - "actionType" : "InfoText", - "actionCode" : "InfoCPBook", - "description" : "People in some parts of England are able to book for an RSV vaccination in Community Pharmacies. Unfortunately, your area does not yet offer RSV vaccinations in that way. You may be able to receive other vaccinations in pharmacies (such as Flu or COVID)" - } ] - } ] - } - }, - "example_50000000003" : { - "summary" : "RSV - Eligible, not actionable", - "value" : { - "responseId" : "1a233ba5-e1eb-4080-a086-2962f6fc3003", - "meta" : { - "lastUpdated" : "2025-02-12T16:11:22Z" - }, - "processedSuggestions" : [ { - "condition" : "RSV", - "status" : "NotActionable", - "statusText" : "Actionable - Individual is eligible but suggest that they need not take any action at this time", - "eligibilityCohorts" : [ { - "cohortCode" : "rsv_75-79_ongoing", - "cohortText" : "You're aged 75 to 79", - "cohortStatus" : "NotActionable" - } ], - "suitabilityRules" : [ { - "ruleType" : "S", - "ruleCode" : "AwaitVaccination", - "ruleText" : "You are in a setting or organisation that will arrange your vaccination for you. For example, if you are in a Care Home or a member of some government organisations." - } ] - } ] - } - }, - "example_50000000004" : { - "summary" : "RSV - Not Eligible Due to Vaccination", - "value" : { - "responseId" : "1a233ba5-e1eb-4080-a086-2962f6fc3004", - "meta" : { - "lastUpdated" : "2025-02-12T16:11:22Z" - }, - "processedSuggestions" : [ { - "condition" : "RSV", - "status" : "NotEligible", - "statusText" : "NotEligible - Individual is not currently eligible", - "eligibilityCohorts" : [ { - "cohortCode" : "rsv_75-79_ongoing", - "cohortText" : "You're aged 75 to 79", - "cohortStatus" : "NotEligible" - } ], - "suitabilityRules" : [ { - "ruleType" : "F", - "ruleCode" : "AlreadyVaccinated", - "ruleText" : "You have already have an RSV vaccination recorded" - } ] - } ] - } - }, - "example_50000000005" : { - "summary" : "RSV - Not Eligible Due to not being cohorted", - "value" : { - "responseId" : "1a233ba5-e1eb-4080-a086-2962f6fc3005", - "meta" : { - "lastUpdated" : "2025-02-12T16:11:22Z" - }, - "processedSuggestions" : [ { - "condition" : "RSV", - "status" : "NotEligible", - "statusText" : "NotEligible - Individual is not currently eligible", - "eligibilityCohorts" : [ { - "cohortCode" : "rsv_75-79_ongoing", - "cohortText" : "You're aged 75 to 79", - "cohortStatus" : "NotEligible" - }, { - "cohortCode" : "rsv_75-79_initial", - "cohortText" : "You turned 80 after 1 September 2024, so are eligible for the RSV vaccine until 31 August 2025", - "cohortStatus" : "NotEligible" - } ] - } ] - } - }, - "example_50000000006" : { - "summary" : "RSV - No rules", - "value" : { - "responseId" : "1a233ba5-e1eb-4080-a086-2962f6fc3006", - "meta" : { - "lastUpdated" : "2025-02-12T16:11:22Z" - } - } - } - }, - "schema" : { - "$ref" : "#/components/schemas/checkEligibility_200_response" - } - } - }, - "description" : "Eligibility response." - }, - "400" : { - "content" : { - "application/fhir+json" : { - "schema" : { - "$ref" : "#/components/schemas/checkEligibility_400_response" - } - } - }, - "description" : "Invalid input data." - }, - "404" : { - "content" : { - "application/fhir+json" : { - "schema" : { - "$ref" : "#/components/schemas/checkEligibility_404_response" - } - } - }, - "description" : "Person not found." - }, - "422" : { - "content" : { - "application/fhir+json" : { - "schema" : { - "$ref" : "#/components/schemas/checkEligibility_422_response" - } - } - }, - "description" : "Unrecognised input data. (Unprocessable Content)" - }, - "500" : { - "content" : { - "application/fhir+json" : { - "schema" : { - "$ref" : "#/components/schemas/checkEligibility_500_response" - } - } - }, - "description" : "Internal server error." - } - }, - "security" : [ { - "app-level0" : [ ] - } ], - "summary" : "Check Eligibility" - } - } - }, - "components" : { - "schemas" : { - "checkEligibility_422_response" : { - "properties" : { - "resourceType" : { - "example" : "OperationOutcome", - "type" : "string" - }, - "id" : { - "example" : "rrt-2959959087381887325-c-geu2-24001-88888888-1", - "type" : "string" - }, - "meta" : { - "$ref" : "#/components/schemas/checkEligibility_400_response_meta" - }, - "issue" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_422_response_issue_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_500_response_issue_inner_details_coding_inner" : { - "properties" : { - "system" : { - "example" : "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", - "type" : "string" - }, - "code" : { - "example" : "SERVICE_ERROR", - "type" : "string" - }, - "display" : { - "example" : "An unknown error occurred processing this request. Contact us for assistance diagnosing this issue: https://digital.nhs.uk/developer/help-and-support quoting the id included in this message", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_200_response_meta" : { - "properties" : { - "lastUpdated" : { - "description" : "Timestamp of when the decisioning evaluation is carried out. This will not change if you receive a cached response.", - "example" : "2025-02-12T16:11:22+00:00", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_422_response_issue_inner_details_coding_inner" : { - "properties" : { - "system" : { - "example" : "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", - "type" : "string" - }, - "code" : { - "example" : "VALIDATION_ERROR", - "type" : "string" - }, - "display" : { - "example" : "The supplied category was not recognised by the API.", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_500_response_meta" : { - "properties" : { - "lastUpdated" : { - "example" : "2025-02-10T13:40:00+00:00", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_400_response_issue_inner_details" : { - "properties" : { - "coding" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_400_response_issue_inner_details_coding_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_404_response" : { - "properties" : { - "resourceType" : { - "example" : "OperationOutcome", - "type" : "string" - }, - "id" : { - "example" : "rrt-2959959087381887325-c-geu2-24001-82918062-1", - "type" : "string" - }, - "meta" : { - "$ref" : "#/components/schemas/checkEligibility_404_response_meta" - }, - "issue" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_404_response_issue_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_200_response" : { - "properties" : { - "responseId" : { - "description" : "GUID assigned when the decisioning evaluation is carried out. This will be useful if you ever need to request support for a particular request. This will not change if you receive a cached response.", - "example" : "1a233ba5-e1eb-4080-a086-2962f6fc3473", - "type" : "string" - }, - "meta" : { - "$ref" : "#/components/schemas/checkEligibility_200_response_meta" - }, - "processedSuggestions" : { - "description" : "List of suggestions the person is eligible for.", - "items" : { - "$ref" : "#/components/schemas/checkEligibility_200_response_processedSuggestions_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_404_response_issue_inner_details" : { - "properties" : { - "coding" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_404_response_issue_inner_details_coding_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_200_response_processedSuggestions_inner_suitabilityRules_inner" : { - "properties" : { - "ruleType" : { - "description" : "The type of a rule that triggered to amend the status of the suggestion", - "enum" : [ "F", "S" ], - "type" : "string" - }, - "ruleCode" : { - "description" : "Machine readable code signifying a rule that amended the status of the suggestion", - "type" : "string" - }, - "ruleText" : { - "description" : "Human readable (render-able) text describing a rule that amended the status of the suggestion", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_200_response_processedSuggestions_inner" : { - "properties" : { - "condition" : { - "description" : "String representing the vaccine target disease, screening target or other scenario requiring decision based suggestions, that this suggestion relates to", - "example" : "RSV", - "type" : "string" - }, - "status" : { - "description" : "String representing an overall summary of the persons status for this processedSuggestion", - "enum" : [ "NotEligible", "NotActionable", "Actionable" ], - "example" : "Actionable", - "type" : "string" - }, - "statusText" : { - "example" : "Actionable - Individual is eligible and we suggest that they follow one or more of the provided actions", - "type" : "string" - }, - "eligibilityCohorts" : { - "description" : "Cohorts that drove the eligibility status returned.", - "example" : [ { - "cohortCode" : "rsv_75-79_initial", - "cohortText" : "You turned 80 after 1 September 2024, so are eligible for the RSV vaccine until 31 August 2025", - "cohortStatus" : "NotEligible" - }, { - "cohortCode" : "rsv_75-79_ongoing", - "cohortText" : "You're aged 75 to 79", - "cohortStatus" : "Actionable" - } ], - "items" : { - "$ref" : "#/components/schemas/checkEligibility_200_response_processedSuggestions_inner_eligibilityCohorts_inner" - }, - "type" : "array" - }, - "suitabilityRules" : { - "description" : "Reasons that the eligibility status was changed from the base eligibility to result in it's status to not be eligible or to be acted on", - "items" : { - "$ref" : "#/components/schemas/checkEligibility_200_response_processedSuggestions_inner_suitabilityRules_inner" - }, - "type" : "array" - }, - "actions" : { - "description" : "List of actions to be shown to the person.", - "items" : { - "$ref" : "#/components/schemas/checkEligibility_200_response_processedSuggestions_inner_actions_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_400_response_issue_inner" : { - "properties" : { - "severity" : { - "example" : "error", - "type" : "string" - }, - "code" : { - "example" : "value", - "type" : "string" - }, - "details" : { - "$ref" : "#/components/schemas/checkEligibility_400_response_issue_inner_details" - }, - "diagnostics" : { - "example" : "FLU&COVID should be a single or comma separated list of condition strings with no other punctuation or special characters", - "type" : "string" - }, - "location" : { - "items" : { - "example" : "parameters/conditions", - "type" : "string" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_400_response_issue_inner_details_coding_inner" : { - "properties" : { - "system" : { - "example" : "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", - "type" : "string" - }, - "code" : { - "example" : "VALIDATION_ERROR", - "type" : "string" - }, - "display" : { - "example" : "The given conditions were not not in the expected format.", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_422_response_issue_inner_details" : { - "properties" : { - "coding" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_422_response_issue_inner_details_coding_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_404_response_issue_inner_details_coding_inner" : { - "properties" : { - "system" : { - "example" : "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", - "type" : "string" - }, - "code" : { - "example" : "RESOURCE_NOT_FOUND", - "type" : "string" - }, - "display" : { - "example" : "The given NHS number was not found in our datasets. This could be because the number is incorrect or some other reason we cannot process that number.", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_400_response_meta" : { - "properties" : { - "lastUpdated" : { - "example" : "2025-02-11T14:40:00+00:00", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_422_response_issue_inner" : { - "properties" : { - "severity" : { - "example" : "error", - "type" : "string" - }, - "code" : { - "example" : "value", - "type" : "string" - }, - "details" : { - "$ref" : "#/components/schemas/checkEligibility_422_response_issue_inner_details" - }, - "diagnostics" : { - "example" : "HEALTHCHECKS is not a category that is supported by the API", - "type" : "string" - }, - "location" : { - "items" : { - "example" : "parameters/category", - "type" : "string" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_400_response" : { - "properties" : { - "resourceType" : { - "example" : "OperationOutcome", - "type" : "string" - }, - "id" : { - "example" : "rrt-2959959087381887325-c-geu2-24001-99999999-1", - "type" : "string" - }, - "meta" : { - "$ref" : "#/components/schemas/checkEligibility_400_response_meta" - }, - "issue" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_400_response_issue_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_200_response_processedSuggestions_inner_actions_inner" : { - "properties" : { - "actionType" : { - "description" : "Type of action to render. E.g. A primary button, a link, text etc", - "type" : "string" - }, - "actionCode" : { - "description" : "Code representing the action to be taken", - "type" : "string" - }, - "description" : { - "description" : "A brief description of the step.", - "type" : "string" - }, - "urlLink" : { - "description" : "URL to invoke if action selected.", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_200_response_processedSuggestions_inner_eligibilityCohorts_inner" : { - "properties" : { - "cohortCode" : { - "description" : "Machine readable code signifying the cohort/cohort group that lead to a person's eligibility for this suggestion", - "type" : "string" - }, - "cohortText" : { - "description" : "Human readable (render-able) text describing the meaning of a cohort/cohort group that lead to a person's eligibility for this suggestion", - "type" : "string" - }, - "cohortStatus" : { - "description" : "String representing the persons status for this processedSuggestion in respect of this particular cohort or cohort group", - "enum" : [ "NotEligible", "NotActionable", "Actionable" ], - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_404_response_issue_inner" : { - "properties" : { - "severity" : { - "example" : "error", - "type" : "string" - }, - "code" : { - "example" : "processing", - "type" : "string" - }, - "details" : { - "$ref" : "#/components/schemas/checkEligibility_404_response_issue_inner_details" - }, - "diagnostics" : { - "example" : "NHS Number 9000000404 was not recognised by the Eligibilty Signposting API", - "type" : "string" - }, - "location" : { - "items" : { - "example" : "parameters/patient", - "type" : "string" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_500_response_issue_inner_details" : { - "properties" : { - "coding" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_500_response_issue_inner_details_coding_inner" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_500_response_issue_inner" : { - "properties" : { - "severity" : { - "example" : "error", - "type" : "string" - }, - "code" : { - "example" : "processing", - "type" : "string" - }, - "details" : { - "$ref" : "#/components/schemas/checkEligibility_500_response_issue_inner_details" - }, - "diagnostics" : { - "example" : "No diagnostics available", - "type" : "string" - }, - "location" : { - "items" : { - "example" : "parameters/category", - "type" : "string" - }, - "type" : "array" - } - }, - "type" : "object" - }, - "checkEligibility_404_response_meta" : { - "properties" : { - "lastUpdated" : { - "example" : "2025-02-14T11:35:00+00:00", - "type" : "string" - } - }, - "type" : "object" - }, - "checkEligibility_500_response" : { - "properties" : { - "resourceType" : { - "example" : "OperationOutcome", - "type" : "string" - }, - "id" : { - "example" : "rrt-2959959087381887325-c-geu2-24001-77777777-1", - "type" : "string" - }, - "meta" : { - "$ref" : "#/components/schemas/checkEligibility_500_response_meta" - }, - "issue" : { - "items" : { - "$ref" : "#/components/schemas/checkEligibility_500_response_issue_inner" - }, - "type" : "array" - } - }, - "type" : "object" - } - }, - "securitySchemes" : { - "app-level0" : { - "description" : "# Application level 0 authentication\n\nThis is an application-restricted authentication pattern for access\nto NHS England APIs. For a full description of our authentication\nand authorization patterns please see\nhttps://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation.\n", - "in" : "header", - "name" : "apikey", - "type" : "apiKey" - } - } - }, - "x-nhsd-apim" : { - "access" : [ ], - "target" : { - "type" : "hosted", - "healthcheck" : "/_status", - "containers" : [ { - "name" : "eligibility-signposting-api", - "image" : { - "name" : "eligibility-signposting-api", - "tag" : "latest" - }, - "environment" : { - "LOG_LEVEL" : "info", - "NODE_ENV" : "production" - } - } ] - }, - "ratelimiting" : [ ] - } -} \ No newline at end of file diff --git a/scripts/config/vale/styles/config/vocabularies/words/accept.txt b/scripts/config/vale/styles/config/vocabularies/words/accept.txt index 8c27ceb..15d8c90 100644 --- a/scripts/config/vale/styles/config/vocabularies/words/accept.txt +++ b/scripts/config/vale/styles/config/vocabularies/words/accept.txt @@ -1,7 +1,9 @@ [A-Z]+s +Apigee Bitwarden bot Cyber +dev Dependabot Gitleaks Grype @@ -10,6 +12,7 @@ OAuth Octokit onboarding Podman +preprod Proxygen Python Redocly @@ -18,3 +21,4 @@ Syft Terraform toolchain Trufflehog +uat diff --git a/specification/README.md b/specification/README.md index 69de8c5..a4ff5b1 100644 --- a/specification/README.md +++ b/specification/README.md @@ -24,20 +24,28 @@ Contains APIM extensions to the OpenAPI specification with deployment requiremen To build a specification for a specific environment: -1. Set the target environment using the `APIM_ENV` parameter -2. Run `make construct-spec` from the repository root, which: +1. Make sure you've run the initial setup command `make install-node`. +2. Set the target environment using the `APIM_ENV` parameter (dev, test, preprod, prod, sandbox) +3. Run `make construct-spec` from the repository root, which: - Updates templates with environment-specific values - - Uses Redocly to compile the complete specification to `build/specification/` -3. For the `sandbox` environment, run `make publish` to convert the specification to JSON and save it to `sandbox/specification/` for immediate use + - Uses Redocly to compile the complete specification to `build/specification/$(APIM_ENV)/` +4. For the `sandbox` environment, run `make generate-sandbox-spec` to convert the specification to JSON and save it to `sandbox/specification/` for immediate use. -### Deploying Environment-Specific Specifications +### Deploying of Environment-Specific Specifications to Apigee See the [Proxygen CLI user guide](https://nhsd-confluence.digital.nhs.uk/spaces/APM/pages/804495095/Proxygen+CLI+user+guide#ProxygenCLIuserguide-Settingupsettingsandcredentials) We deploy our specifications using the Proxygen CLI. In order to do this, the following steps need to be performed: -1. Construct the specification for the environment of your choice, following the instructions above. -2. Run `make retrieve-proxygen-key` from the root directory to retrieve the private key needed to authenticate with Proxygen. -3. Run `make setup-proxygen-credentials` from the root directory to set up credentials needed to interact with our API proxy. -4. Run `proxygen instance deploy eligibility-signposting-api ./build/specification/eligibility-signposting-api.yaml` to deploy the specification to +1. Construct the specification for the environment of your choice, following the instructions above. This will be stored in +2. Activate a poetry environment `poetry env activate` - you may need to run `make install-python` to install poetry etc. first. +3. Run `make retrieve-proxygen-key` from the root directory to retrieve the private key needed to authenticate with Proxygen. +4. Run `make setup-proxygen-credentials` from the root directory to set up credentials needed to interact with our API proxy. +5. Run `proxygen instance deploy eligibility-signposting-api ./build/specification/eligibility-signposting-api.yaml` to deploy the specification to a chosen environment. + +### Publishing specifications + +1. To get the currently published specification run `make get-spec` for production or `make get-spec-uat` for non-production. This will return an error if a specification is not deployed. +2. To publish a specification, generate an appropriate specification (prod for production, preprod for uat) above then run `make publish-spec` for production or `make publish-spec-uat` for non-production. +3. To delete a specification, run `make delete-spec` for production or `make delete-spec-uat` for non-production diff --git a/specification/components/security/security-dev.yaml b/specification/components/security/security-dev.yaml new file mode 100644 index 0000000..7074f33 --- /dev/null +++ b/specification/components/security/security-dev.yaml @@ -0,0 +1 @@ +$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9 diff --git a/specification/components/security/security-preprod.yaml b/specification/components/security/security-preprod.yaml new file mode 100644 index 0000000..7074f33 --- /dev/null +++ b/specification/components/security/security-preprod.yaml @@ -0,0 +1 @@ +$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9 diff --git a/specification/components/security/security-prod.yaml b/specification/components/security/security-prod.yaml new file mode 100644 index 0000000..7074f33 --- /dev/null +++ b/specification/components/security/security-prod.yaml @@ -0,0 +1 @@ +$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9 diff --git a/specification/components/security/security-sandbox.yaml b/specification/components/security/security-sandbox.yaml index 6efacb9..96e5804 100644 --- a/specification/components/security/security-sandbox.yaml +++ b/specification/components/security/security-sandbox.yaml @@ -1 +1 @@ -$ref: https://proxygen.ptl.api.platform.nhs.uk/components/securitySchemes/app-level0 +$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/app-level0 diff --git a/specification/components/security/security-test.yaml b/specification/components/security/security-test.yaml new file mode 100644 index 0000000..7074f33 --- /dev/null +++ b/specification/components/security/security-test.yaml @@ -0,0 +1 @@ +$ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9 diff --git a/specification/eligibility-signposting-api.yaml b/specification/eligibility-signposting-api.yaml index 7517cdf..64e0ab9 100644 --- a/specification/eligibility-signposting-api.yaml +++ b/specification/eligibility-signposting-api.yaml @@ -11,11 +11,11 @@ tags: - name: Signposting - name: NextActions servers: - - url: https://sandbox.api.service.nhs.uk/eligibility-signposting + - url: https://sandbox.api.service.nhs.uk/eligibility-signposting-api description: Sandbox Server - - url: https://int.api.service.nhs.uk/eligibility-signposting + - url: https://int.api.service.nhs.uk/eligibility-signposting-api description: Integration Server - - url: https://api.service.nhs.uk/eligibility-signposting + - url: https://api.service.nhs.uk/eligibility-signposting-api description: Production Server paths: /patient-check/{id}: diff --git a/specification/postman/collection.json b/specification/postman/collection.json new file mode 100644 index 0000000..f9e85d6 --- /dev/null +++ b/specification/postman/collection.json @@ -0,0 +1,1209 @@ +{ + "_": { + "postman_id": "ba20edf8-d2b0-449e-9fce-c2fca677a75f" + }, + "item": [ + { + "id": "bda40fa4-a13e-480b-b308-5d8ffea5c219", + "name": "Eligibility", + "description": { + "content": "", + "type": "text/plain" + }, + "item": [], + "event": [] + }, + { + "id": "3baf66b1-6fd6-4541-9bcc-4882580840bf", + "name": "Signposting", + "description": { + "content": "", + "type": "text/plain" + }, + "item": [], + "event": [] + }, + { + "id": "2dcd7738-4fb2-40bd-908d-d20e055faf84", + "name": "NextActions", + "description": { + "content": "", + "type": "text/plain" + }, + "item": [], + "event": [] + }, + { + "id": "25891a9a-2789-4669-ab95-32606f384701", + "name": "Check Eligibility", + "request": { + "name": "Check Eligibility", + "description": { + "content": "Determines which suggestions a person is eligible for and which they are not, including reasons and next steps.", + "type": "text/plain" + }, + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [ + { + "disabled": false, + "description": { + "content": "(Required) The NHS number of the person to check eligibility for. The primary identifier of a patient, unique within NHS England and Wales. Always 10 digits and must be a [valid NHS number](https://www.datadictionary.nhs.uk/attributes/nhs_number.html).", + "type": "text/plain" + }, + "type": "any", + "value": "9000000009", + "key": "id" + } + ] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "method": "GET", + "body": {}, + "auth": { + "type": "apikey", + "apikey": [ + { + "type": "any", + "value": "apikey", + "key": "key" + }, + { + "type": "any", + "value": "{{apiKey}}", + "key": "value" + }, + { + "type": "any", + "value": "header", + "key": "in" + } + ] + } + }, + "response": [ + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "9a9149f3-e174-4b0d-a723-122e6331ea19", + "name": "RSV - Actionable CP Booking", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"responseId\": \"1a233ba5-e1eb-4080-a086-2962f6fc3473\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-12T16:11:22Z\"\n },\n \"processedSuggestions\": [\n {\n \"condition\": \"RSV\",\n \"status\": \"Actionable\",\n \"statusText\": \"Actionable - Individual is eligible and we suggest that they follow one or more of the provided actions\",\n \"eligibilityCohorts\": [\n {\n \"cohortCode\": \"rsv_75-79_ongoing\",\n \"cohortText\": \"You're aged 75 to 79\",\n \"cohortStatus\": \"Actionable\"\n }\n ],\n \"actions\": [\n {\n \"actionType\": \"PrimaryButton\",\n \"actionCode\": \"NationalCPBook\",\n \"description\": \"Book or Amend an RSV vaccinations appointment\",\n \"urlLink\": \"http://www.nhs.uk/book-rsv\"\n },\n {\n \"actionType\": \"InfoText\",\n \"actionCode\": \"AwaitGPContact\",\n \"description\": \"You can wait for your GP surgery to contact you about getting the RSV vaccine. This may be by letter, text, phone call or email.\"\n }\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "31ac0790-21bb-476d-96fa-c134d6a4b507", + "name": "RSV - Actionable Not CP Booking", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"responseId\": \"1a233ba5-e1eb-4080-a086-2962f6fc3002\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-12T16:11:22Z\"\n },\n \"processedSuggestions\": [\n {\n \"condition\": \"RSV\",\n \"status\": \"Actionable\",\n \"statusText\": \"Actionable - Individual is eligible and we suggest that they follow one or more of the provided actions\",\n \"eligibilityCohorts\": [\n {\n \"cohortCode\": \"rsv_75-79_ongoing\",\n \"cohortText\": \"You're aged 75 to 79\",\n \"cohortStatus\": \"Actionable\"\n }\n ],\n \"actions\": [\n {\n \"actionType\": \"InfoText\",\n \"actionCode\": \"AwaitGPContact\",\n \"description\": \"You can wait for your GP surgery to contact you about getting the RSV vaccine. This may be by letter, text, phone call or email.\"\n },\n {\n \"actionType\": \"InfoText\",\n \"actionCode\": \"InfoCPBook\",\n \"description\": \"People in some parts of England are able to book for an RSV vaccination in Community Pharmacies. Unfortunately, your area does not yet offer RSV vaccinations in that way. You may be able to receive other vaccinations in pharmacies (such as Flu or COVID)\"\n }\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "e96c6a4d-f77f-4775-90a4-e2520150f08e", + "name": "RSV - Eligible, not actionable", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"responseId\": \"1a233ba5-e1eb-4080-a086-2962f6fc3003\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-12T16:11:22Z\"\n },\n \"processedSuggestions\": [\n {\n \"condition\": \"RSV\",\n \"status\": \"NotActionable\",\n \"statusText\": \"Actionable - Individual is eligible but suggest that they need not take any action at this time\",\n \"eligibilityCohorts\": [\n {\n \"cohortCode\": \"rsv_75-79_ongoing\",\n \"cohortText\": \"You're aged 75 to 79\",\n \"cohortStatus\": \"NotActionable\"\n }\n ],\n \"suitabilityRules\": [\n {\n \"ruleType\": \"S\",\n \"ruleCode\": \"AwaitVaccination\",\n \"ruleText\": \"You are in a setting or organisation that will arrange your vaccination for you. For example, if you are in a Care Home or a member of some government organisations.\"\n }\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "4284a77d-b38a-44cd-aeb9-d7606a954917", + "name": "RSV - Not Eligible Due to Vaccination", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"responseId\": \"1a233ba5-e1eb-4080-a086-2962f6fc3004\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-12T16:11:22Z\"\n },\n \"processedSuggestions\": [\n {\n \"condition\": \"RSV\",\n \"status\": \"NotEligible\",\n \"statusText\": \"NotEligible - Individual is not currently eligible\",\n \"eligibilityCohorts\": [\n {\n \"cohortCode\": \"rsv_75-79_ongoing\",\n \"cohortText\": \"You're aged 75 to 79\",\n \"cohortStatus\": \"NotEligible\"\n }\n ],\n \"suitabilityRules\": [\n {\n \"ruleType\": \"F\",\n \"ruleCode\": \"AlreadyVaccinated\",\n \"ruleText\": \"You have already have an RSV vaccination recorded\"\n }\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "60101a57-018e-40f8-b01f-1ccb2f5c0647", + "name": "RSV - Not Eligible Due to not being cohorted", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"responseId\": \"1a233ba5-e1eb-4080-a086-2962f6fc3005\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-12T16:11:22Z\"\n },\n \"processedSuggestions\": [\n {\n \"condition\": \"RSV\",\n \"status\": \"NotEligible\",\n \"statusText\": \"NotEligible - Individual is not currently eligible\",\n \"eligibilityCohorts\": [\n {\n \"cohortCode\": \"rsv_75-79_ongoing\",\n \"cohortText\": \"You're aged 75 to 79\",\n \"cohortStatus\": \"NotEligible\"\n },\n {\n \"cohortCode\": \"rsv_75-79_initial\",\n \"cohortText\": \"You turned 80 after 1 September 2024, so are eligible for the RSV vaccine until 31 August 2025\",\n \"cohortStatus\": \"NotEligible\"\n }\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "b2a046d8-f574-4ac2-ab9c-898f000a3ca8", + "name": "RSV - No rules", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "OK", + "code": 200, + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": "{\n \"responseId\": \"1a233ba5-e1eb-4080-a086-2962f6fc3006\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-12T16:11:22Z\"\n }\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "237e32fb-9df9-48dd-a8ef-9c7369a0d02d", + "name": "Invalid input data.", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/fhir+json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Bad Request", + "code": 400, + "header": [ + { + "key": "Content-Type", + "value": "application/fhir+json" + } + ], + "body": "{\n \"resourceType\": \"OperationOutcome\",\n \"id\": \"rrt-2959959087381887325-c-geu2-24001-99999999-1\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-11T14:40:00+00:00\"\n },\n \"issue\": [\n {\n \"severity\": \"error\",\n \"code\": \"value\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The given conditions were not not in the expected format.\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The given conditions were not not in the expected format.\"\n }\n ]\n },\n \"diagnostics\": \"FLU&COVID should be a single or comma separated list of condition strings with no other punctuation or special characters\",\n \"location\": [\n \"parameters/conditions\",\n \"parameters/conditions\"\n ]\n },\n {\n \"severity\": \"error\",\n \"code\": \"value\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The given conditions were not not in the expected format.\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The given conditions were not not in the expected format.\"\n }\n ]\n },\n \"diagnostics\": \"FLU&COVID should be a single or comma separated list of condition strings with no other punctuation or special characters\",\n \"location\": [\n \"parameters/conditions\",\n \"parameters/conditions\"\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "25ddc8a7-450f-48df-97e1-a19bb7166b7a", + "name": "Person not found.", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/fhir+json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Not Found", + "code": 404, + "header": [ + { + "key": "Content-Type", + "value": "application/fhir+json" + } + ], + "body": "{\n \"resourceType\": \"OperationOutcome\",\n \"id\": \"rrt-2959959087381887325-c-geu2-24001-82918062-1\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-14T11:35:00+00:00\"\n },\n \"issue\": [\n {\n \"severity\": \"error\",\n \"code\": \"processing\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"RESOURCE_NOT_FOUND\",\n \"display\": \"The given NHS number was not found in our datasets. This could be because the number is incorrect or some other reason we cannot process that number.\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"RESOURCE_NOT_FOUND\",\n \"display\": \"The given NHS number was not found in our datasets. This could be because the number is incorrect or some other reason we cannot process that number.\"\n }\n ]\n },\n \"diagnostics\": \"NHS Number 9000000404 was not recognised by the Eligibilty Signposting API\",\n \"location\": [\n \"parameters/patient\",\n \"parameters/patient\"\n ]\n },\n {\n \"severity\": \"error\",\n \"code\": \"processing\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"RESOURCE_NOT_FOUND\",\n \"display\": \"The given NHS number was not found in our datasets. This could be because the number is incorrect or some other reason we cannot process that number.\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"RESOURCE_NOT_FOUND\",\n \"display\": \"The given NHS number was not found in our datasets. This could be because the number is incorrect or some other reason we cannot process that number.\"\n }\n ]\n },\n \"diagnostics\": \"NHS Number 9000000404 was not recognised by the Eligibilty Signposting API\",\n \"location\": [\n \"parameters/patient\",\n \"parameters/patient\"\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "83e75dfb-0131-4aac-958d-965f3ab06893", + "name": "Unrecognised input data. (Unprocessable Content)", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/fhir+json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Unprocessable Entity (WebDAV) (RFC 4918)", + "code": 422, + "header": [ + { + "key": "Content-Type", + "value": "application/fhir+json" + } + ], + "body": "{\n \"resourceType\": \"OperationOutcome\",\n \"id\": \"rrt-2959959087381887325-c-geu2-24001-88888888-1\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-11T14:40:00+00:00\"\n },\n \"issue\": [\n {\n \"severity\": \"error\",\n \"code\": \"value\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The supplied category was not recognised by the API.\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The supplied category was not recognised by the API.\"\n }\n ]\n },\n \"diagnostics\": \"HEALTHCHECKS is not a category that is supported by the API\",\n \"location\": [\n \"parameters/category\",\n \"parameters/category\"\n ]\n },\n {\n \"severity\": \"error\",\n \"code\": \"value\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The supplied category was not recognised by the API.\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"VALIDATION_ERROR\",\n \"display\": \"The supplied category was not recognised by the API.\"\n }\n ]\n },\n \"diagnostics\": \"HEALTHCHECKS is not a category that is supported by the API\",\n \"location\": [\n \"parameters/category\",\n \"parameters/category\"\n ]\n }\n ]\n}", + "cookie": [] + }, + { + "_": { + "postman_previewlanguage": "json" + }, + "id": "5942e808-a5d9-4109-826b-e7f003400b17", + "name": "Internal server error.", + "originalRequest": { + "url": { + "path": [ + "patient-check", + ":id" + ], + "host": [ + "{{baseUrl}}" + ], + "query": [ + { + "disabled": true, + "description": { + "content": "The category for which the caller is checking eligibility suggestions. If not provided, eligibility for all supported categories will be checked.", + "type": "text/plain" + }, + "key": "category", + "value": "VACCINATIONS" + }, + { + "disabled": true, + "description": { + "content": "The diseases or conditions for which the caller is checking eligibility suggestions in a comma separated list. If not provided, eligibility for all supported diseases will be checked.", + "type": "text/plain" + }, + "key": "conditions", + "value": "FLU,RSV" + }, + { + "disabled": true, + "description": { + "content": "When Y is passed in, the API response will include zero or more actions as applicable. Passing in N will result in no actions being calculated or returned.", + "type": "text/plain" + }, + "key": "includeActions", + "value": "Y" + } + ], + "variable": [] + }, + "header": [ + { + "disabled": true, + "description": { + "content": "A globally unique identifier (GUID) for the request, which we use to de-duplicate repeated requests and to trace the request if you contact our helpdesk.\n\nMust be a universally unique identifier (UUID) (ideally version 4).\n\nMirrored back in a response header.\n\nIf you re-send a failed request, use the same value in this header.\n", + "type": "text/plain" + }, + "key": "X-Request-ID", + "value": "60E0B220-8136-4CA5-AE46-1D97EF59D068" + }, + { + "disabled": true, + "description": { + "content": "An optional ID which you can use to track transactions across multiple systems. It can take any value, but we recommend avoiding `.` characters.\n\nMirrored back in a response header.\n", + "type": "text/plain" + }, + "key": "X-Correlation-ID", + "value": "11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA" + }, + { + "disabled": true, + "description": { + "content": "The ODS code of the user.\n\nMandatory for client applications which service multiple end user organisations (EUO). This will allow the calls to be attributed to the correct EUO.\n", + "type": "text/plain" + }, + "key": "NHSD-End-User-Organisation-ODS", + "value": "Y12345" + }, + { + "key": "Accept", + "value": "application/fhir+json" + }, + { + "description": { + "content": "Added as a part of security scheme: apikey", + "type": "text/plain" + }, + "key": "apikey", + "value": "" + } + ], + "method": "GET", + "body": {} + }, + "status": "Internal Server Error", + "code": 500, + "header": [ + { + "key": "Content-Type", + "value": "application/fhir+json" + } + ], + "body": "{\n \"resourceType\": \"OperationOutcome\",\n \"id\": \"rrt-2959959087381887325-c-geu2-24001-77777777-1\",\n \"meta\": {\n \"lastUpdated\": \"2025-02-10T13:40:00+00:00\"\n },\n \"issue\": [\n {\n \"severity\": \"error\",\n \"code\": \"processing\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"SERVICE_ERROR\",\n \"display\": \"An unknown error occurred processing this request. Contact us for assistance diagnosing this issue: https://digital.nhs.uk/developer/help-and-support quoting the id included in this message\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"SERVICE_ERROR\",\n \"display\": \"An unknown error occurred processing this request. Contact us for assistance diagnosing this issue: https://digital.nhs.uk/developer/help-and-support quoting the id included in this message\"\n }\n ]\n },\n \"diagnostics\": \"No diagnostics available\",\n \"location\": [\n \"parameters/category\",\n \"parameters/category\"\n ]\n },\n {\n \"severity\": \"error\",\n \"code\": \"processing\",\n \"details\": {\n \"coding\": [\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"SERVICE_ERROR\",\n \"display\": \"An unknown error occurred processing this request. Contact us for assistance diagnosing this issue: https://digital.nhs.uk/developer/help-and-support quoting the id included in this message\"\n },\n {\n \"system\": \"https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode\",\n \"code\": \"SERVICE_ERROR\",\n \"display\": \"An unknown error occurred processing this request. Contact us for assistance diagnosing this issue: https://digital.nhs.uk/developer/help-and-support quoting the id included in this message\"\n }\n ]\n },\n \"diagnostics\": \"No diagnostics available\",\n \"location\": [\n \"parameters/category\",\n \"parameters/category\"\n ]\n }\n ]\n}", + "cookie": [] + } + ], + "event": [ + { + "listen": "test", + "script": { + "id": "00e0af41-bf6e-4224-87d6-f92cbb6d39d3", + "type": "text/javascript", + "exec": [ + "// Validate status 2xx \npm.test(\"[GET]::/patient-check/:id - Status code is 2xx\", function () {\n pm.response.to.be.success;\n});\n", + "// Validate if response header has matching content-type\npm.test(\"[GET]::/patient-check/:id - Content-Type is application/json\", function () {\n pm.expect(pm.response.headers.get(\"Content-Type\")).to.include(\"application/json\");\n});\n", + "// Validate if response has JSON Body \npm.test(\"[GET]::/patient-check/:id - Response has JSON Body\", function () {\n pm.response.to.have.jsonBody();\n});\n", + "// Response Validation\nconst schema = {\"type\":\"object\",\"properties\":{\"responseId\":{\"type\":\"string\",\"description\":\"GUID assigned when the decisioning evaluation is carried out. This will be useful if you ever need to request support for a particular request. This will not change if you receive a cached response.\"},\"meta\":{\"type\":\"object\",\"properties\":{\"lastUpdated\":{\"type\":\"string\",\"description\":\"Timestamp of when the decisioning evaluation is carried out. This will not change if you receive a cached response.\"}}},\"processedSuggestions\":{\"type\":\"array\",\"description\":\"List of suggestions the person is eligible for.\",\"items\":{\"type\":\"object\",\"properties\":{\"condition\":{\"type\":\"string\",\"description\":\"String representing the vaccine target disease, screening target or other scenario requiring decision based suggestions, that this suggestion relates to\"},\"status\":{\"type\":\"string\",\"description\":\"String representing an overall summary of the persons status for this processedSuggestion\",\"enum\":[\"NotEligible\",\"NotActionable\",\"Actionable\"]},\"statusText\":{\"type\":\"string\"},\"eligibilityCohorts\":{\"type\":\"array\",\"description\":\"Cohorts that drove the eligibility status returned.\",\"items\":{\"type\":\"object\",\"properties\":{\"cohortCode\":{\"type\":\"string\",\"description\":\"Machine readable code signifying the cohort/cohort group that lead to a person's eligibility for this suggestion\"},\"cohortText\":{\"type\":\"string\",\"description\":\"Human readable (render-able) text describing the meaning of a cohort/cohort group that lead to a person's eligibility for this suggestion\"},\"cohortStatus\":{\"type\":\"string\",\"description\":\"String representing the persons status for this processedSuggestion in respect of this particular cohort or cohort group\",\"enum\":[\"NotEligible\",\"NotActionable\",\"Actionable\"]}}}},\"suitabilityRules\":{\"type\":\"array\",\"description\":\"Reasons that the eligibility status was changed from the base eligibility to result in it's status to not be eligible or to be acted on\",\"items\":{\"type\":\"object\",\"properties\":{\"ruleType\":{\"type\":\"string\",\"description\":\"The type of a rule that triggered to amend the status of the suggestion\",\"enum\":[\"F\",\"S\"]},\"ruleCode\":{\"type\":\"string\",\"description\":\"Machine readable code signifying a rule that amended the status of the suggestion\"},\"ruleText\":{\"type\":\"string\",\"description\":\"Human readable (render-able) text describing a rule that amended the status of the suggestion\"}}}},\"actions\":{\"type\":\"array\",\"description\":\"List of actions to be shown to the person.\",\"items\":{\"type\":\"object\",\"properties\":{\"actionType\":{\"type\":\"string\",\"description\":\"Type of action to render. E.g. A primary button, a link, text etc\"},\"actionCode\":{\"type\":\"string\",\"description\":\"Code representing the action to be taken\"},\"description\":{\"type\":\"string\",\"description\":\"A brief description of the step.\"},\"urlLink\":{\"type\":\"string\",\"description\":\"URL to invoke if action selected.\"}}}}}}}}}\n\n// Validate if response matches JSON schema \npm.test(\"[GET]::/patient-check/:id - Schema is valid\", function() {\n pm.response.to.have.jsonSchema(schema,{unknownFormats: [\"int32\", \"int64\", \"float\", \"double\"]});\n});\n" + ] + } + } + ], + "protocolProfileBehavior": { + "disableBodyPruning": true + } + } + ], + "event": [], + "variable": [ + { + "type": "any", + "value": "https://sandbox.api.service.nhs.uk/eligibility-signposting-api", + "key": "baseUrl" + } + ], + "info": { + "_postman_id": "ba20edf8-d2b0-449e-9fce-c2fca677a75f", + "name": "Patient Eligibility Signposting API", + "version": { + "raw": "1.0.9-alpha", + "major": 1, + "minor": 0, + "patch": 9, + "prerelease": "alpha", + "build": [], + "string": "1.0.9-alpha" + }, + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "description": { + "content": "## Overview\n Use this API to access the [Patient Eligibility Signposting Data Product](https://digital.nhs.uk/services/eligibility-signposting) - the nationally curated single source of eligibility status and signposted actions for individuals. For example, you can request eligibility for one or more vaccination types to understand if NHS England holds information which suggest that the person could or should take further steps toward receiving those vaccinations, and optionally, a list of the steps NHS England would recommend.\n \n Where someone is deemed eligible, they will also be classified as actionable or not actionable. When deemed not actionable, one or more reasons will be returned. These reasons can range from personal care setting impacts to current lack of availability of vaccines and more.\n \n The API returns most of its data in both code and text form. Unless agreed with NHS England, where text is provided it should be displayed to the user as-is.\n \n This API currently has a single User Restricted access mode and will operate only in the context of the authenticated individual, you may however request:\n * eligibility for all supported vaccinations\n * eligibility for specified supported vaccinations\n * request that actions be included in the response\n * request that actions not be included in the response\n \n You cannot currently use this API to:\n * request eligibility for proxy people (familial relations etc.)\n * request actions for people considered ineligible\n \n This API is read-only and can return a list of processed suggestions, each relating to a 'condition' (e.g. COVID, RSV, BOWEL, EYE, BREAST etc.), including the following information for each:\n * a code representing the condition (COVID, RSV, BOWEL, EYE, BREAST)\n * an overall status (NotEligible, NotActionable, Actionable)\n * a list of eligibility cohort groups to which the person belongs (when eligible)\n * a list of the cohort groups that could have made the person eligible (when not eligible)\n * a list of rules/reasons that deem a person to be NotActionable\n * a list of actions that should be shown to the consumer\n \n #### Definitions of Overall Status \n \nThe overall status values indicate the following:\n \n* NotEligible - the individual does not currently meet eligibility criteria\n* NotActionable - the individual is eligible but does not need to take any further action at this time\n* Actionable - the individual is eligible and should follow one of the recommended actions provided\n \n### Patients included in the Patient Eligibility Signposting API\n The API will return data for all patients who are in the NHS PDS system that are registered with an English GP practice (or one administered by England) or who we believe to be resident in England. \n \n Patients who are deceased (or thought to be), marked as invalid or sensitive will not be processed by this API.\n \n ## Who can use this API\n This API can only be used where there is a [legal basis](https://digital.nhs.uk/services/eligibility-signposting/legal-basis) to do so. Make sure you have a valid use case before you go too far with your development. You must demonstrate you have a [valid use case](https://digital.nhs.uk/services/eligibility-signposting/legal-basis) as part of digital onboarding. \n \n You must do this before you can go live (see 'Onboarding' below).\n \n ### Who can access Eligibility Signposting Information\n Patients who receive health and social care or make use of NHS services in England, Wales and the Isle of Man can access their own Eligibility Signposting data through onboarded services.\n \n Health and care organisations in England and the Isle of Man can access our information for legitimate direct care purposes. Legitimate direct care examples include NHS organisations delivering healthcare, local authorities delivering care, third sector and private sector health and care organisations, and developers delivering systems to health and care organisations. \n \n \n ### Existing API users\n To find out which healthcare software development organisations and products are already using this API, see [Patient Eligibility Signposting API - integrated products](https://digital.nhs.uk/services/eligibility-signposting/integrated-products).\n \n ## Access modes\n This API currently has only one access mode:\n * patient access \n \n We are considering the possibility of adding other modes in the future:\n * healthcare worker access \n * restricted access \n \n ### Patient access \n If the end user is a patient then you must use this access mode. Use this access mode to obtain data for that patient.\n \n This access mode is [user-restricted](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation#user-restricted-apis), meaning an end user must be present, authenticated and authorised. \n \n The end user must be: \n * a patient who receives health and social care or makes use of NHS services \n * strongly authenticated, using [NHS login](https://digital.nhs.uk/services/nhs-login)\n \n To use this access mode, use one of the following security patterns:\n \n |\tSecurity pattern\t\t |\tTechnical details\t |\tAdvantages\t | Disadvantages |\n |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------------------------------------------------| ------------------------------------------------------------|---------------------------------------------------------|\n |[NHS login - combined authentication and authorisation](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/user-restricted-restful-apis-nhs-login-combined-authentication-and-authorisation) |OAuth 2.0 authorisation code with API key and secret |No need to integrate and onboard separately with NHS login. |No access to user information. |\n |[NHS login - separate authentication and authorisation](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/user-restricted-restful-apis-nhs-login-separate-authentication-and-authorisation) |OAuth 2.0 token exchange with signed JWT |Gives access to user information. |Need to integrate and onboard separately with NHS login. |\n \n Patient access mode users must be authenticated to a high proofing level (P9) and to one of the following [vectors of trust](https://nhsconnect.github.io/nhslogin/vectors-of-trust/): \n * P9.Cp.Cd\n * P9.Cp.Ck\n * P9.Cm\n \n This access mode is available in production ([beta](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#api-status)).\n \n ### Restricted access\n This access mode is not yet available, if you believe this mode would benefit your use-case, please let us know.\n \n This access mode is [application-restricted](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation#application-restricted-apis), meaning we authenticate and authorise the calling application but not the end user. \n \n This access mode is not designed to be accessed by an end user. You might use this access mode as part of a back-end process to: \n * retrieve eligibility signposting information into a system in advance of a clinic\n * retrieve eligibility signposting information into a system to be used in a disconnected manner\n \n To use this access mode, use this security pattern:\n * [Application-restricted RESTful API - signed JWT authentication](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/application-restricted-restful-apis-signed-jwt-authentication)\n \n ## Roadmap\n The [Patient Eligibility Signposting API](https://digital.nhs.uk/services/eligibility-signposting/roadmap-and-strategy) roadmap shows the planned changes for the API. \n \n To see our roadmap, or to suggest, comment or vote on features for this API, see our [interactive product backlog](https://nhs-digital-api-management.featureupvote.com/suggestions/612352/eligibility-signposting-api-vaccinations).\n \n If you have any other queries, please [contact us](https://digital.nhs.uk/developer/help-and-support).\n \n ## Service level\n \n This API is a silver service, meaning it is operational 24 hours a day, 365 days a year and supported 8am to 6pm, Monday to Friday excluding bank holidays.\n \n For more details, see [service levels](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#service-levels).\n \n ## Rate limits\n \n The default rate limit is 25TPS (Transactions Per Second), per app. If you require a higher rate limit please [contact us](https://digital.nhs.uk/developer/help-and-support). or raise this during the onboarding process.\n \n ## Technology\n This API is [RESTful](https://digital.nhs.uk/developer/guides-and-documentation/our-api-technologies#basic-rest).\n \n ## Network access\n This API is available on the internet and, indirectly, on the [Health and Social Care Network (HSCN)](https://digital.nhs.uk/services/health-and-social-care-network).\n \n For more details see [Network access for APIs](https://digital.nhs.uk/developer/guides-and-documentation/network-access-for-apis).\n \n ## Errors\n We use standard HTTP status codes to show whether an API request succeeded or not. They are usually in the range:\n \n * 200 to 299 if it succeeded, including code 202 if it was accepted by an API that needs to wait for further action\n * 400 to 499 if it failed because of a client error by your application\n * 500 to 599 if it failed because of an error on our server\n \n Errors specific to each API are shown in the Endpoints section, under Response. See our [reference guide](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#http-status-codes) for more on errors.\n \n Your API-calling application should have a mechanism to automatically try again, for example by giving status information to your end user, before giving up. See our [reference guide](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#error-handling) for more information about error handling.\n \n ## Open source\n You might find the following [open source](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#open-source) resources useful:\n \n | Resource | Description | Links |\n |---------------------------|----------------------------------------------------------------------|--------------------------------------------------------------------------------|\n | Patient Eligibility Signposting API| Source code including API proxy, sandbox and specification and code. | [GitHub repo](https://github.com/NHSDigital/eligibility-signposting-api) |\n \n We currently don't have any open source client libraries or sample code for this API. If you think this would be useful, you can [upvote the suggestion on our Interactive Product Backlog](https://nhs-digital-api-management.featureupvote.com/suggestions/107439/client-libraries-and-reference-implementations).\n \n \n \n ## Environments and testing\n \n | Environment | Base URL |\n | ----------------- | ---------------------------------------------------------------------- |\n | Sandbox | `https://sandbox.api.service.nhs.uk/eligibility-signposting/patient-check/{id}` |\n | Integration test | `https://int.api.service.nhs.uk/eligibility-signposting/patient-check/{id}` |\n | Production | `https://api.service.nhs.uk/eligibility-signposting/patient-check/{id}` |\n \n ### Sandbox testing\n Our [sandbox environment](https://digital.nhs.uk/developer/guides-and-documentation/testing#sandbox-testing):\n * is for early developer testing\n * only covers a limited set of scenarios\n * is open access, so does not allow you to test authorisation\n \n For details of sandbox test scenarios, or to try out the sandbox using our 'Try this API' feature, see the documentation for each endpoint.\n \n Alternatively, you can try out the sandbox using our Postman collection:\n \n [![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/?????????????????????????????????)\n \n ### Integration testing\n Our [integration test environment](https://digital.nhs.uk/developer/guides-and-documentation/testing#integration-testing):\n * is for formal integration testing\n * includes authorisation, with options for user-restricted access (NHS Login) \n ### Production smoke testing\n You must not use real patient data for smoke testing in the production environment.\n \n Rather, use our [production test patient](https://digital.nhs.uk/services/eligibility-signposting/api-test-data#production-smoke-testing).\n \n ## Onboarding\n You need to get your software approved by us before it can go live with this API. We call this onboarding. The onboarding process can sometimes be quite long, so it is worth planning well ahead.\n \n As part of this process, you need to demonstrate your technical conformance to the requirements for this API. \n \n You also need to demonstrate that you can manage risks. This might impact the design of your software. For details, see [Onboarding support information](https://digital.nhs.uk/services/eligibility-signposting/onboarding-support-information).\n \n To understand how our online digital onboarding process works, see [digital onboarding](https://digital.nhs.uk/developer/guides-and-documentation/digital-onboarding). \n \n \n ## Related APIs\n \n The following APIs are related to this API:\n\n", + "type": "text/plain" + } + } +} diff --git a/specification/x-nhsd-apim/access-dev.yaml b/specification/x-nhsd-apim/access-dev.yaml new file mode 100644 index 0000000..0ddbf59 --- /dev/null +++ b/specification/x-nhsd-apim/access-dev.yaml @@ -0,0 +1,3 @@ +- title: Eligibility Signposting API (Dev Environment) + grants: + nhs-login-p9: [] diff --git a/specification/x-nhsd-apim/access-preprod.yaml b/specification/x-nhsd-apim/access-preprod.yaml new file mode 100644 index 0000000..b3c4695 --- /dev/null +++ b/specification/x-nhsd-apim/access-preprod.yaml @@ -0,0 +1,3 @@ +- title: Eligibility Signposting API (Pre Production Environment) + grants: + nhs-login-p9: [] diff --git a/specification/x-nhsd-apim/access-prod.yaml b/specification/x-nhsd-apim/access-prod.yaml new file mode 100644 index 0000000..db8110e --- /dev/null +++ b/specification/x-nhsd-apim/access-prod.yaml @@ -0,0 +1,3 @@ +- title: Eligibility Signposting API (Production Environment) + grants: + nhs-login-p9: [] diff --git a/specification/x-nhsd-apim/access-test.yaml b/specification/x-nhsd-apim/access-test.yaml new file mode 100644 index 0000000..3a175cc --- /dev/null +++ b/specification/x-nhsd-apim/access-test.yaml @@ -0,0 +1,3 @@ +- title: Eligibility Signposting API (Test Environment) + grants: + nhs-login-p9: [] diff --git a/specification/x-nhsd-apim/ratelimit-dev.yaml b/specification/x-nhsd-apim/ratelimit-dev.yaml new file mode 100644 index 0000000..1dafe5a --- /dev/null +++ b/specification/x-nhsd-apim/ratelimit-dev.yaml @@ -0,0 +1,3 @@ +proxy: + limit: 5 + timeunit: second diff --git a/specification/x-nhsd-apim/ratelimit-preprod.yaml b/specification/x-nhsd-apim/ratelimit-preprod.yaml new file mode 100644 index 0000000..035b7e7 --- /dev/null +++ b/specification/x-nhsd-apim/ratelimit-preprod.yaml @@ -0,0 +1,3 @@ +proxy: + limit: 20 + timeunit: second diff --git a/specification/x-nhsd-apim/ratelimit-prod.yaml b/specification/x-nhsd-apim/ratelimit-prod.yaml new file mode 100644 index 0000000..1dafe5a --- /dev/null +++ b/specification/x-nhsd-apim/ratelimit-prod.yaml @@ -0,0 +1,3 @@ +proxy: + limit: 5 + timeunit: second diff --git a/specification/x-nhsd-apim/ratelimit-test.yaml b/specification/x-nhsd-apim/ratelimit-test.yaml new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/specification/x-nhsd-apim/ratelimit-test.yaml @@ -0,0 +1 @@ +[] diff --git a/specification/x-nhsd-apim/target-dev.yaml b/specification/x-nhsd-apim/target-dev.yaml new file mode 100644 index 0000000..a4dca6a --- /dev/null +++ b/specification/x-nhsd-apim/target-dev.yaml @@ -0,0 +1,6 @@ +type: external +url: "TBC" +healthcheck: /_status +security: + type: mtls + secret: eligibility-signposting-api diff --git a/specification/x-nhsd-apim/target-preprod.yaml b/specification/x-nhsd-apim/target-preprod.yaml new file mode 100644 index 0000000..a4dca6a --- /dev/null +++ b/specification/x-nhsd-apim/target-preprod.yaml @@ -0,0 +1,6 @@ +type: external +url: "TBC" +healthcheck: /_status +security: + type: mtls + secret: eligibility-signposting-api diff --git a/specification/x-nhsd-apim/target-prod.yaml b/specification/x-nhsd-apim/target-prod.yaml new file mode 100644 index 0000000..a4dca6a --- /dev/null +++ b/specification/x-nhsd-apim/target-prod.yaml @@ -0,0 +1,6 @@ +type: external +url: "TBC" +healthcheck: /_status +security: + type: mtls + secret: eligibility-signposting-api diff --git a/specification/x-nhsd-apim/target-test.yaml b/specification/x-nhsd-apim/target-test.yaml new file mode 100644 index 0000000..20938ef --- /dev/null +++ b/specification/x-nhsd-apim/target-test.yaml @@ -0,0 +1,10 @@ +type: hosted +healthcheck: /_status +containers: + - name: eligibility-signposting-api + image: + name: eligibility-signposting-api + tag: latest + environment: + LOG_LEVEL: info + NODE_ENV: production