From 3b396dfe4accb47889982bf4c68908554a04e1f9 Mon Sep 17 00:00:00 2001 From: Anjali Trace Date: Mon, 13 Apr 2026 16:26:26 +0100 Subject: [PATCH 1/8] NRL-2140 Pass environment name (dev-sandbox) to get permissions step rather than account name (dev) --- .github/workflows/persistent-environment.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/persistent-environment.yml b/.github/workflows/persistent-environment.yml index 8c9b751bc..b352e5a63 100644 --- a/.github/workflows/persistent-environment.yml +++ b/.github/workflows/persistent-environment.yml @@ -54,9 +54,8 @@ jobs: env: ENVIRONMENT: ${{ inputs.environment }} run: | - account=$(echo "$ENVIRONMENT" | cut -d '-' -f1) inactive_stack=$(poetry run python ./scripts/get_env_config.py inactive-stack $ENVIRONMENT) - make get-s3-perms ENV=${account} TF_WORKSPACE_NAME=${inactive_stack} + make get-s3-perms ENV=$ENVIRONMENT TF_WORKSPACE_NAME=${inactive_stack} USE_SHARED_RESOURCES=true - name: Save Build Artifacts uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 From 97480ef406192bcdadf3741bc38825c76f88280e Mon Sep 17 00:00:00 2001 From: Matt Dean Date: Tue, 14 Apr 2026 14:26:14 +0100 Subject: [PATCH 2/8] [NRL-2140] Add sandbox perms to perms layer --- scripts/get_s3_permissions.py | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/scripts/get_s3_permissions.py b/scripts/get_s3_permissions.py index 02030a8a7..c84698c06 100644 --- a/scripts/get_s3_permissions.py +++ b/scripts/get_s3_permissions.py @@ -276,6 +276,48 @@ def add_smoke_test_files(secretsmanager, local_path, env_name): ] +def add_sandbox_files(local_path): + """Add the permissions required for the sandbox environments. + Only call this function if your want to add sandbox permissions. + These permissions are taken from the existing permissions in the API repos. + """ + sandbox_app_id = "NRL-SANDBOX-APP" + nrl_sandbox_perms = { + "RJ11": [ + "http://snomed.info/sct|736253001", + "http://snomed.info/sct|736253002", + ], + # These ones are needed for the Seed data + "Y05868": [ + "http://snomed.info/sct|736253002", + "http://snomed.info/sct|887701000000100", + "http://snomed.info/sct|1363501000000100", + "http://snomed.info/sct|861421000000109", + ], + "8J008": ["http://snomed.info/sct|1363501000000100"], + "RY26A": ["http://snomed.info/sct|861421000000109"], + # This one is needed for Smoke Tests + "RM559": ["http://snomed.info/sct|736253002"], + } + + for ods_code, snomed_codes in nrl_sandbox_perms.items(): + _write_permission_file( + Path.joinpath(local_path, "producer", sandbox_app_id), + ods_code, + snomed_codes, + ) + _write_permission_file( + Path.joinpath(local_path, "consumer", sandbox_app_id), + ods_code, + snomed_codes, + ) + _write_v1_permission_file( + Path.joinpath(local_path, sandbox_app_id), + ods_code, + snomed_codes, + ) + + def download_files( s3_client, bucket_name, local_path, file_names, folders, secretsmanager, env_name ): @@ -297,6 +339,9 @@ def download_files( add_feature_test_files(local_path) add_smoke_test_files(secretsmanager, local_path, env_name) + if env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"]: + add_sandbox_files(local_path) + def main(use_shared_resources: str, env: str, workspace: str, path_to_store: str): stack_name = env if use_shared_resources else workspace From c1a9d5a32100640e25db326a8a24e444c2bb3ac4 Mon Sep 17 00:00:00 2001 From: Matt Dean Date: Tue, 14 Apr 2026 14:57:31 +0100 Subject: [PATCH 3/8] [NRL-2140] WIP - Enabled reporting in dev --- terraform/infrastructure/etc/dev.tfvars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/infrastructure/etc/dev.tfvars b/terraform/infrastructure/etc/dev.tfvars index 9467886a1..545fb4742 100644 --- a/terraform/infrastructure/etc/dev.tfvars +++ b/terraform/infrastructure/etc/dev.tfvars @@ -9,4 +9,4 @@ public_domain = "internal-dev.api.service.nhs.uk" public_sandbox_domain = "internal-dev-sandbox.api.service.nhs.uk" log_retention_period = 90 -enable_reporting = false +enable_reporting = true From d071a479c5afbae6092312724692a2bfe697dd5b Mon Sep 17 00:00:00 2001 From: Matt Dean Date: Tue, 14 Apr 2026 15:23:53 +0100 Subject: [PATCH 4/8] NRL-2140 Use PointerTypes constants for types in sandbox config --- scripts/get_s3_permissions.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/scripts/get_s3_permissions.py b/scripts/get_s3_permissions.py index c84698c06..45c9506d6 100644 --- a/scripts/get_s3_permissions.py +++ b/scripts/get_s3_permissions.py @@ -284,20 +284,25 @@ def add_sandbox_files(local_path): sandbox_app_id = "NRL-SANDBOX-APP" nrl_sandbox_perms = { "RJ11": [ - "http://snomed.info/sct|736253001", - "http://snomed.info/sct|736253002", + PointerTypes.MENTAL_HEALTH_PLAN.value, # http://snomed.info/sct|736253002 ], # These ones are needed for the Seed data "Y05868": [ - "http://snomed.info/sct|736253002", - "http://snomed.info/sct|887701000000100", - "http://snomed.info/sct|1363501000000100", - "http://snomed.info/sct|861421000000109", + PointerTypes.MENTAL_HEALTH_PLAN.value, # http://snomed.info/sct|736253002 + PointerTypes.EMERGENCY_HEALTHCARE_PLAN.value, # http://snomed.info/sct|887701000000100 + PointerTypes.NEWS2_CHART.value, # http://snomed.info/sct|1363501000000100 + PointerTypes.EOL_COORDINATION_SUMMARY.value, # http://snomed.info/sct|861421000000109 ], - "8J008": ["http://snomed.info/sct|1363501000000100"], - "RY26A": ["http://snomed.info/sct|861421000000109"], + "8J008": [ + PointerTypes.NEWS2_CHART.value + ], # http://snomed.info/sct|1363501000000100 + "RY26A": [ + PointerTypes.EOL_COORDINATION_SUMMARY.value + ], # http://snomed.info/sct|861421000000109 # This one is needed for Smoke Tests - "RM559": ["http://snomed.info/sct|736253002"], + "RM559": [ + PointerTypes.MENTAL_HEALTH_PLAN.value + ], # http://snomed.info/sct|736253002 } for ods_code, snomed_codes in nrl_sandbox_perms.items(): From 0882c6ea0a11439014d87e9f55f2b3f3d7c75153 Mon Sep 17 00:00:00 2001 From: Matt Dean Date: Tue, 14 Apr 2026 15:43:10 +0100 Subject: [PATCH 5/8] NRL-2140 Add debug when getting perms for sandbox --- scripts/get_s3_permissions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/get_s3_permissions.py b/scripts/get_s3_permissions.py index 45c9506d6..e6c2fc7bf 100644 --- a/scripts/get_s3_permissions.py +++ b/scripts/get_s3_permissions.py @@ -345,6 +345,7 @@ def download_files( add_smoke_test_files(secretsmanager, local_path, env_name) if env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"]: + print(f"Adding sandbox permissions for {env_name} to temporary directory...") add_sandbox_files(local_path) From d1b586dc070e7b3b6b4c6ecd60c28907a0353f35 Mon Sep 17 00:00:00 2001 From: Matt Dean Date: Tue, 14 Apr 2026 19:01:46 +0100 Subject: [PATCH 6/8] NRL-2140 Always use smoke_test_params ods_code for sandbox smoke tests --- tests/smoke/scenarios/1dsync_upsert_delete.py | 3 ++- tests/smoke/scenarios/consumer_search_read_v1.py | 14 +++++++++++--- tests/smoke/scenarios/producer_crud_v1.py | 12 ++++++++++-- tests/smoke/scenarios/producer_search_read_v1.py | 15 ++++++++++++--- 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/tests/smoke/scenarios/1dsync_upsert_delete.py b/tests/smoke/scenarios/1dsync_upsert_delete.py index 6fbc682c5..60aab4d98 100644 --- a/tests/smoke/scenarios/1dsync_upsert_delete.py +++ b/tests/smoke/scenarios/1dsync_upsert_delete.py @@ -15,7 +15,8 @@ def producer_client_1dsync( if environment_config.connect_mode == ConnectMode.INTERNAL.value: custom_smoke_test_parameters.nrlf_app_id = "SMOKETEST1DSYNC" - custom_smoke_test_parameters.ods_code = "SMOKETEST1DSYNC" + if environment_config.env_name not in ["dev-sandbox", "qa-sandbox", "int-sandbox"]: + custom_smoke_test_parameters.ods_code = "SMOKETEST1DSYNC" client_config = environment_config.to_client_config(custom_smoke_test_parameters) diff --git a/tests/smoke/scenarios/consumer_search_read_v1.py b/tests/smoke/scenarios/consumer_search_read_v1.py index cfb26eb9c..9fb9c253d 100644 --- a/tests/smoke/scenarios/consumer_search_read_v1.py +++ b/tests/smoke/scenarios/consumer_search_read_v1.py @@ -2,7 +2,7 @@ import pytest -from tests.smoke.environment import SmokeTestParameters +from tests.smoke.environment import EnvironmentConfig, SmokeTestParameters from tests.smoke.setup import build_document_reference, upsert_test_pointer from tests.utilities.api_clients import ConsumerTestClient, ProducerTestClient @@ -12,8 +12,16 @@ def test_data_v1( test_nhs_numbers: list[str], producer_client_v1: ProducerTestClient, smoke_test_parameters: SmokeTestParameters, -) -> Generator[str, Any, None]: - test_ods_code = smoke_test_parameters.v1_ods_code + environment_config: EnvironmentConfig, +) -> Generator[dict[str, Any], Any, None]: + if ( + environment_config.env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"] + and smoke_test_parameters.ods_code + ): + test_ods_code = smoke_test_parameters.ods_code + else: + test_ods_code = smoke_test_parameters.v1_ods_code + test_pointers = [ upsert_test_pointer( f"{test_ods_code}-smoketest_consumer_search_read_pointer_{n}", diff --git a/tests/smoke/scenarios/producer_crud_v1.py b/tests/smoke/scenarios/producer_crud_v1.py index 4db76cb20..50012fa6c 100644 --- a/tests/smoke/scenarios/producer_crud_v1.py +++ b/tests/smoke/scenarios/producer_crud_v1.py @@ -1,4 +1,4 @@ -from tests.smoke.environment import SmokeTestParameters +from tests.smoke.environment import EnvironmentConfig, SmokeTestParameters from tests.smoke.setup import build_document_reference from tests.utilities.api_clients import ProducerTestClient @@ -7,11 +7,19 @@ def test_smoke_producer_crud_v1( producer_client_v1: ProducerTestClient, test_nhs_numbers: list[str], smoke_test_parameters: SmokeTestParameters, + environment_config: EnvironmentConfig, ): """ Smoke test scenario for producer CRUD behaviour """ - test_ods_code = smoke_test_parameters.v1_ods_code + if ( + environment_config.env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"] + and smoke_test_parameters.ods_code + ): + test_ods_code = smoke_test_parameters.ods_code + else: + test_ods_code = smoke_test_parameters.v1_ods_code + test_docref = build_document_reference( nhs_number=test_nhs_numbers[0], custodian=test_ods_code ) diff --git a/tests/smoke/scenarios/producer_search_read_v1.py b/tests/smoke/scenarios/producer_search_read_v1.py index 83f92009e..f7f93ce2e 100644 --- a/tests/smoke/scenarios/producer_search_read_v1.py +++ b/tests/smoke/scenarios/producer_search_read_v1.py @@ -2,7 +2,7 @@ import pytest -from tests.smoke.environment import SmokeTestParameters +from tests.smoke.environment import EnvironmentConfig, SmokeTestParameters from tests.smoke.setup import build_document_reference, upsert_test_pointer from tests.utilities.api_clients import ProducerTestClient @@ -12,8 +12,17 @@ def test_data( test_nhs_numbers: list[str], producer_client_v1: ProducerTestClient, smoke_test_parameters: SmokeTestParameters, -) -> Generator[str, Any, None]: - test_ods_code = smoke_test_parameters.v1_ods_code + environment_config: EnvironmentConfig, +) -> Generator[dict[str, Any], Any, None]: + + if ( + environment_config.env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"] + and smoke_test_parameters.ods_code + ): + test_ods_code = smoke_test_parameters.ods_code + else: + test_ods_code = smoke_test_parameters.v1_ods_code + test_pointers = [ upsert_test_pointer( f"{test_ods_code}-smoketest_producer_count_search_read_pointer_{n}", From 4b9772daf56a410d11b56c4df2978512c1d673eb Mon Sep 17 00:00:00 2001 From: Matt Dean Date: Tue, 14 Apr 2026 19:22:21 +0100 Subject: [PATCH 7/8] NRL-2140 Fixup smoketest v1 clients to support sandbox smoketests --- tests/smoke/conftest.py | 30 ++++++++++++++----- tests/smoke/scenarios/1dsync_upsert_delete.py | 7 ++++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/tests/smoke/conftest.py b/tests/smoke/conftest.py index 4916affc8..56bed11ac 100644 --- a/tests/smoke/conftest.py +++ b/tests/smoke/conftest.py @@ -55,11 +55,18 @@ def producer_client_v1( environment_config: EnvironmentConfig, smoke_test_parameters: SmokeTestParameters ) -> ProducerTestClient: config = environment_config.to_client_config(smoke_test_parameters) + + if ( + environment_config.env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"] + and smoke_test_parameters.ods_code + ): + client_ods_code = smoke_test_parameters.ods_code + else: + client_ods_code = smoke_test_parameters.v1_ods_code + if environment_config.connect_mode == ConnectMode.INTERNAL: - config.connection_metadata.ods_code = smoke_test_parameters.v1_ods_code - config.custom_headers["NHSD-End-User-Organisation-ODS"] = ( - smoke_test_parameters.v1_ods_code - ) + config.connection_metadata.ods_code = client_ods_code + config.custom_headers["NHSD-End-User-Organisation-ODS"] = client_ods_code return ProducerTestClient(config=config) @@ -68,11 +75,18 @@ def consumer_client_v1( environment_config: EnvironmentConfig, smoke_test_parameters: SmokeTestParameters ) -> ConsumerTestClient: config = environment_config.to_client_config(smoke_test_parameters) + + if ( + environment_config.env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"] + and smoke_test_parameters.ods_code + ): + client_ods_code = smoke_test_parameters.ods_code + else: + client_ods_code = smoke_test_parameters.v1_ods_code + if environment_config.connect_mode == ConnectMode.INTERNAL: - config.connection_metadata.ods_code = smoke_test_parameters.v1_ods_code - config.custom_headers["NHSD-End-User-Organisation-ODS"] = ( - smoke_test_parameters.v1_ods_code - ) + config.connection_metadata.ods_code = client_ods_code + config.custom_headers["NHSD-End-User-Organisation-ODS"] = client_ods_code return ConsumerTestClient(config=config) diff --git a/tests/smoke/scenarios/1dsync_upsert_delete.py b/tests/smoke/scenarios/1dsync_upsert_delete.py index 60aab4d98..58a0c1da9 100644 --- a/tests/smoke/scenarios/1dsync_upsert_delete.py +++ b/tests/smoke/scenarios/1dsync_upsert_delete.py @@ -26,12 +26,17 @@ def producer_client_1dsync( def test_smoke_1dsync_upsert_delete( producer_client_1dsync: ProducerTestClient, smoke_test_parameters: SmokeTestParameters, + environment_config: EnvironmentConfig, test_nhs_numbers: list[str], ): """ Smoke test scenario for 1dsync upsert and delete behaviour """ - test_ods_code = "SMOKETEST1DSYNC" + if environment_config.env_name in ["dev-sandbox", "qa-sandbox", "int-sandbox"]: + test_ods_code = smoke_test_parameters.ods_code + else: + test_ods_code = "SMOKETEST1DSYNC" + test_docref = build_document_reference( nhs_number=test_nhs_numbers[0], custodian=test_ods_code ) From e5ab47f0c26f8d9ed62b4501ee418adbb6e78736 Mon Sep 17 00:00:00 2001 From: mattdean3-nhs Date: Wed, 15 Apr 2026 12:05:12 +0100 Subject: [PATCH 8/8] Apply suggestion from @anjalitrace2-nhs Co-authored-by: Anjali Trace --- scripts/get_s3_permissions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/get_s3_permissions.py b/scripts/get_s3_permissions.py index e6c2fc7bf..32c2ded05 100644 --- a/scripts/get_s3_permissions.py +++ b/scripts/get_s3_permissions.py @@ -279,7 +279,7 @@ def add_smoke_test_files(secretsmanager, local_path, env_name): def add_sandbox_files(local_path): """Add the permissions required for the sandbox environments. Only call this function if your want to add sandbox permissions. - These permissions are taken from the existing permissions in the API repos. + These permissions are taken from the existing permissions in the API proxy repos. """ sandbox_app_id = "NRL-SANDBOX-APP" nrl_sandbox_perms = {