diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6dc0eb8cd..4c80c758d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: rev: v1.4.0 hooks: - id: detect-secrets - exclude: ".pre-commit-config.yaml|infrastructure/localstack/provider.tf|src/etl/sds/tests/changelog" + exclude: ".pre-commit-config.yaml|infrastructure/localstack/provider.tf|src/etl/sds/tests/changelog|src/etl/sds/worker/bulk/transform_bulk/tests|src/etl/sds/worker/bulk/tests/stage_data" - repo: https://github.com/prettier/pre-commit rev: 57f39166b5a5a504d6808b87ab98d41ebf095b46 diff --git a/CHANGELOG.md b/CHANGELOG.md index e272cd7ab..1488fb3a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 2024-12-05 +- [PI-631] Generate Product Ids +- [PI-691] Allow devs to clear terminal after each Feature Test +- [PI-618] Bulk ETL + ## 2024-12-02 - [PI-572] Create an AS Device - [PI-582] AS Additional Interations smoke test diff --git a/README.md b/README.md index d5137a95a..b9b83fbe0 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ 4. [Workflow](#workflow) 5. [Swagger](#swagger) 6. [ETL](#etl) +7. [Administration](#administration) --- @@ -429,6 +430,18 @@ and make etl--clear-state WORKSPACE=dev SET_CHANGELOG_NUMBER=540210 ``` +## Administration + +### Generating Ids + +In order to generate a persistent list of Ids across environments then run... (The example given will generate 100 ids.) + +``` +make admin--generate-ids--product SET_GENERATOR_COUNT=100 +``` + +Any previously generated ids will not be overwritten. + ### Documentation We have several locations for the Swagger to keep things as visible as possible diff --git a/VERSION b/VERSION index 2eaf6b095..c74a5222b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2024.12.02 +2024.12.05 diff --git a/changelog/2024-12-05.md b/changelog/2024-12-05.md new file mode 100644 index 000000000..adc388690 --- /dev/null +++ b/changelog/2024-12-05.md @@ -0,0 +1,3 @@ +- [PI-631] Generate Product Ids +- [PI-691] Allow devs to clear terminal after each Feature Test +- [PI-618] Bulk ETL diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram--bulk-transform-and-load.asl.json b/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram--bulk-transform-and-load.asl.json index 57e9d834f..8175b1335 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram--bulk-transform-and-load.asl.json +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram--bulk-transform-and-load.asl.json @@ -26,6 +26,43 @@ "BackoffRate": 2 } ], + "Next": "transform-result" + }, + "transform-result": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.error_message", + "IsNull": true, + "Next": "load-fanout" + } + ], + "Default": "pass" + }, + "pass": { + "Type": "Pass", + "End": true + }, + "load-fanout": { + "Type": "Task", + "Resource": "arn:aws:states:::lambda:invoke", + "OutputPath": "$.Payload", + "Parameters": { + "FunctionName": "${load_fanout_worker_arn}:$LATEST" + }, + "Retry": [ + { + "ErrorEquals": [ + "Lambda.ServiceException", + "Lambda.AWSLambdaException", + "Lambda.SdkClientException", + "Lambda.TooManyRequestsException" + ], + "IntervalSeconds": 1, + "MaxAttempts": 3, + "BackoffRate": 2 + } + ], "Next": "Map" }, "Map": { diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram.asl.json b/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram.asl.json index 031caba90..a6ca7f6da 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram.asl.json +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/etl-diagram.asl.json @@ -75,7 +75,7 @@ "OutputPath": "$.Payload", "Parameters": { "Payload": {}, - "FunctionName": "${extract_worker_arn}:$LATEST" + "FunctionName": "${extract_worker_bulk_arn}:$LATEST" }, "Retry": [ { @@ -151,7 +151,7 @@ "OutputPath": "$.Payload", "Parameters": { "Payload": {}, - "FunctionName": "${extract_worker_arn}:$LATEST" + "FunctionName": "${extract_worker_update_arn}:$LATEST" }, "Retry": [ { diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/main.tf b/infrastructure/terraform/per_workspace/modules/etl/sds/main.tf index 6671399fd..16325c57d 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/main.tf +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/main.tf @@ -46,10 +46,11 @@ module "sds_layer" { } } -module "worker_extract" { - source = "./worker/" +module "worker_extract_bulk" { + source = "./worker" - etl_stage = "extract" + etl_stage = "extract_bulk" + etl_type = "bulk" etl_name = local.etl_name assume_account = var.assume_account workspace_prefix = var.workspace_prefix @@ -80,10 +81,47 @@ module "worker_extract" { } +module "worker_extract_update" { + source = "./worker" + + etl_stage = "extract_update" + etl_type = "update" + etl_name = local.etl_name + assume_account = var.assume_account + workspace_prefix = var.workspace_prefix + python_version = var.python_version + etl_bucket_name = module.bucket.s3_bucket_id + layers = [var.event_layer_arn, var.third_party_core_layer_arn, module.etl_layer.lambda_layer_arn, module.sds_layer.lambda_layer_arn, var.domain_layer_arn] + + policy_json = <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "s3:PutObject", + "s3:AbortMultipartUpload", + "s3:GetBucketLocation", + "s3:GetObject", + "s3:ListBucket", + "s3:ListBucketMultipartUploads", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": ["${module.bucket.s3_bucket_arn}", "${module.bucket.s3_bucket_arn}/*"] + } + ] + } + EOT + +} + + module "worker_transform_bulk" { - source = "./worker/" + source = "./worker" etl_stage = "transform_bulk" + etl_type = "bulk" etl_name = local.etl_name assume_account = var.assume_account workspace_prefix = var.workspace_prefix @@ -111,6 +149,13 @@ module "worker_transform_bulk" { "Effect": "Allow", "Resource": ["${module.bucket.s3_bucket_arn}", "${module.bucket.s3_bucket_arn}/*"] }, + { + "Action": [ + "dynamodb:Query" + ], + "Effect": "Allow", + "Resource": ["${var.table_arn}", "${var.table_arn}/*"] + }, { "Action": [ "kms:Decrypt" @@ -125,9 +170,10 @@ module "worker_transform_bulk" { } module "worker_transform_update" { - source = "./worker/" + source = "./worker" etl_stage = "transform_update" + etl_type = "update" etl_name = local.etl_name assume_account = var.assume_account workspace_prefix = var.workspace_prefix @@ -174,12 +220,55 @@ module "worker_transform_update" { EOT } +module "worker_load_bulk_fanout" { + source = "./worker" + + etl_stage = "load_bulk_fanout" + etl_type = "bulk" + etl_name = local.etl_name + assume_account = var.assume_account + workspace_prefix = var.workspace_prefix + python_version = var.python_version + etl_bucket_name = module.bucket.s3_bucket_id + layers = [var.event_layer_arn, var.third_party_core_layer_arn, module.etl_layer.lambda_layer_arn, module.sds_layer.lambda_layer_arn, var.domain_layer_arn] + + policy_json = <<-EOT + { + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "s3:PutObject", + "s3:AbortMultipartUpload", + "s3:GetBucketLocation", + "s3:GetObject", + "s3:ListBucket", + "s3:ListBucketMultipartUploads", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": ["${module.bucket.s3_bucket_arn}", "${module.bucket.s3_bucket_arn}/*"] + }, + { + "Action": [ + "kms:Decrypt" + ], + "Effect": "Allow", + "Resource": ["*"] + } + ] + } + EOT + +} + module "worker_load_bulk" { - source = "./worker/" + source = "./worker" etl_stage = "load_bulk" + etl_type = "bulk" etl_name = local.etl_name assume_account = var.assume_account workspace_prefix = var.workspace_prefix @@ -227,9 +316,10 @@ module "worker_load_bulk" { } module "worker_load_update" { - source = "./worker/" + source = "./worker" etl_stage = "load_update" + etl_type = "update" etl_name = local.etl_name assume_account = var.assume_account workspace_prefix = var.workspace_prefix @@ -279,9 +369,10 @@ module "worker_load_update" { } module "worker_load_bulk_reduce" { - source = "./worker/" + source = "./worker" etl_stage = "load_bulk_reduce" + etl_type = "bulk" etl_name = local.etl_name assume_account = var.assume_account workspace_prefix = var.workspace_prefix @@ -321,6 +412,7 @@ module "bulk_transform_and_load_step_function" { "${path.module}/etl-diagram--bulk-transform-and-load.asl.json", { transform_worker_arn = module.worker_transform_bulk.arn + load_fanout_worker_arn = module.worker_load_bulk_fanout.arn load_worker_arn = module.worker_load_bulk.arn load_reduce_worker_arn = module.worker_load_bulk_reduce.arn bulk_load_chunksize = var.bulk_load_chunksize @@ -332,9 +424,11 @@ module "bulk_transform_and_load_step_function" { lambda = { lambda = [ module.worker_transform_bulk.arn, + module.worker_load_bulk_fanout.arn, module.worker_load_bulk.arn, module.worker_load_bulk_reduce.arn, "${module.worker_transform_bulk.arn}:*", + "${module.worker_load_bulk_fanout.arn}:*", "${module.worker_load_bulk.arn}:*", "${module.worker_load_bulk_reduce.arn}:*" @@ -404,7 +498,8 @@ resource "aws_sfn_state_machine" "state_machine" { definition = templatefile( "${path.module}/etl-diagram.asl.json", { - extract_worker_arn = module.worker_extract.arn + extract_worker_bulk_arn = module.worker_extract_bulk.arn + extract_worker_update_arn = module.worker_extract_update.arn notify_arn = module.notify.arn etl_bucket = module.bucket.s3_bucket_id changelog_key = var.changelog_key diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/output.tf b/infrastructure/terraform/per_workspace/modules/etl/sds/output.tf index 02215bedb..ccb43ae79 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/output.tf +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/output.tf @@ -29,3 +29,7 @@ output "etl_state_lock_enforcer" { output "manual_trigger_arn" { value = module.trigger_manual.arn } + +output "bulk_load_lambda_arn" { + value = module.worker_load_bulk.arn +} diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/step_function_role.tf b/infrastructure/terraform/per_workspace/modules/etl/sds/step_function_role.tf index df7b24b86..292130ff6 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/step_function_role.tf +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/step_function_role.tf @@ -10,13 +10,15 @@ locals { lambda = { actions = ["lambda:InvokeFunction"] resources = [ - module.worker_extract.arn, + module.worker_extract_bulk.arn, + module.worker_extract_update.arn, module.worker_transform_bulk.arn, module.worker_transform_update.arn, module.worker_load_bulk.arn, module.worker_load_update.arn, module.notify.arn, - "${module.worker_extract.arn}:*", + "${module.worker_extract_bulk.arn}:*", + "${module.worker_extract_update.arn}:*", "${module.worker_transform_bulk.arn}:*", "${module.worker_transform_update.arn}:*", "${module.worker_load_bulk.arn}:*", diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/vars.tf b/infrastructure/terraform/per_workspace/modules/etl/sds/vars.tf index 73f4f4721..31d29b2ee 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/vars.tf +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/vars.tf @@ -10,11 +10,11 @@ variable "changelog_key" { default = "changelog-number" } variable "bulk_transform_chunksize" { - default = 500 + default = 100000 } variable "bulk_load_chunksize" { - default = 1000 # needs to be larger than 'bulk_transform_chunksize' in the case of overflow + default = 1000000 # needs to be larger than 'bulk_transform_chunksize' in the case of overflow } variable "etl_state_lock_key" { diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/worker/main.tf b/infrastructure/terraform/per_workspace/modules/etl/sds/worker/main.tf index 840a13ca0..36797a8da 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/worker/main.tf +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/worker/main.tf @@ -4,7 +4,7 @@ module "lambda_function" { function_name = "${var.workspace_prefix}--${var.etl_name}--${var.etl_stage}" description = "${replace(var.workspace_prefix, "_", "-")} ${var.etl_name} (${var.etl_stage}) lambda function" - handler = "etl.sds.worker.${var.etl_stage}.${var.etl_stage}.handler" + handler = "etl.sds.worker.${var.etl_type}.${var.etl_stage}.${var.etl_stage}.handler" runtime = var.python_version timeout = 600 memory_size = 10240 @@ -26,7 +26,7 @@ module "lambda_function" { create_package = false - local_existing_package = "${path.root}/../../../src/etl/sds/worker/${var.etl_stage}/dist/${var.etl_stage}.zip" + local_existing_package = "${path.root}/../../../src/etl/sds/worker/${var.etl_type}/${var.etl_stage}/dist/${var.etl_stage}.zip" tags = { Name = "${var.workspace_prefix}--${var.etl_name}--${var.etl_stage}" diff --git a/infrastructure/terraform/per_workspace/modules/etl/sds/worker/vars.tf b/infrastructure/terraform/per_workspace/modules/etl/sds/worker/vars.tf index c24ef70ff..e80bc5538 100644 --- a/infrastructure/terraform/per_workspace/modules/etl/sds/worker/vars.tf +++ b/infrastructure/terraform/per_workspace/modules/etl/sds/worker/vars.tf @@ -6,6 +6,10 @@ variable "etl_name" { type = string } +variable "etl_type" { + type = string +} + variable "etl_stage" { type = string } diff --git a/pyproject.toml b/pyproject.toml index 8cc2973af..eeadc2ec6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,18 +1,18 @@ [tool.poetry] name = "connecting-party-manager" -version = "2024.12.02" +version = "2024.12.05" description = "Repository for the Connecting Party Manager API and related services" authors = ["NHS England"] license = "LICENSE.md" readme = "README.md" packages = [ - { include = "api", from = "src" }, - { include = "domain", from = "src/layers" }, - { include = "event", from = "src/layers" }, - { include = "api_utils", from = "src/layers" }, - { include = "etl_utils", from = "src/layers" }, - { include = "sds", from = "src/layers" }, - { include = "builder", from = "scripts" }, + { include = "api", from = "src" }, + { include = "domain", from = "src/layers" }, + { include = "event", from = "src/layers" }, + { include = "api_utils", from = "src/layers" }, + { include = "etl_utils", from = "src/layers" }, + { include = "sds", from = "src/layers" }, + { include = "builder", from = "scripts" }, ] [tool.poetry.dependencies] @@ -46,16 +46,18 @@ pyyaml = "^6.0.1" proxygen-cli = "^2.1.14" moto = "^5.0.1" boto3-stubs = { extras = [ - "dynamodb", - "iam", - "lambda", - "s3", - "sqs", - "secretsmanager", - "stepfunctions", + "dynamodb", + "iam", + "lambda", + "s3", + "sqs", + "secretsmanager", + "stepfunctions", ], version = "^1.34.37" } pytest-timeout = "^2.2.0" lz4 = "^4.3.3" +pytest-repeat = "^0.9.3" +click = "^8.1.7" [tool.poetry.group.local] optional = true diff --git a/scripts/administration/administration.mk b/scripts/administration/administration.mk new file mode 100644 index 000000000..e29d54da4 --- /dev/null +++ b/scripts/administration/administration.mk @@ -0,0 +1,4 @@ +SET_GENERATOR_COUNT := + +admin--generate-ids--product: ## Generate product Ids + poetry run python scripts/administration/id_generator.py --count="$(SET_GENERATOR_COUNT)" diff --git a/scripts/administration/id_generator.py b/scripts/administration/id_generator.py new file mode 100644 index 000000000..08510f1a3 --- /dev/null +++ b/scripts/administration/id_generator.py @@ -0,0 +1,56 @@ +import argparse +import json +import os + +from domain.core.cpm_system_id import ProductId + +ID_FILE_MAP = { + "product": f"{os.getcwd()}/src/layers/domain/core/cpm_system_id/generated_ids/product_ids.json", +} + +ID_CLASS_MAP = { + "product": ProductId, +} + + +def generator(id_type="product"): + id_class = ID_CLASS_MAP.get(id_type) + generator = id_class.create() + return generator.__root__ + + +def open_file(id_type="product"): + if os.path.exists(ID_FILE_MAP.get(id_type)): + with open(ID_FILE_MAP.get(id_type), "r") as file: + return set(json.load(file)) + return set() + + +def save_file(ids, id_type="product"): + with open(ID_FILE_MAP.get(id_type), "w") as file: + json.dump(list(ids), file) + + +def bulk_generator(id_count=1, id_type="product"): + ids = open_file(id_type=id_type) + starting_id_count = len(ids) + while len(ids) - starting_id_count < id_count: + ids.add(generator()) + save_file(ids, id_type) + return ids + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Generate unique Product Ids.") + parser.add_argument( + "--count", type=int, default=1, help="Number of Product Ids to generate." + ) + args = parser.parse_args() + ids = bulk_generator(args.count) + id_type = "product" + print(f"Generated {id_type.capitalize()} Ids...") # noqa + print("========================") # noqa + for id in ids: + print(id) # noqa + + print("========================") # noqa diff --git a/scripts/builder/build.mk b/scripts/builder/build.mk index 3797f79e4..fdc0bf360 100644 --- a/scripts/builder/build.mk +++ b/scripts/builder/build.mk @@ -32,7 +32,7 @@ clean--build: build: $(BUILD_TIMESTAMP) ## Complete project install and build artifacts for deployment $(BUILD_TIMESTAMP): $(BUILD_DEPENDENCIES) - @find $(CURDIR) -name make.py | xargs -I % bash -c 'poetry run python %' + @find $(CURDIR) -name make.py | xargs -n 1 -P 8 -I % bash -c 'poetry run python %' touch $(BUILD_TIMESTAMP) generate--sbom: build diff --git a/scripts/etl/clear_state_inputs.py b/scripts/etl/clear_state_inputs.py index 392fae801..b5d191092 100644 --- a/scripts/etl/clear_state_inputs.py +++ b/scripts/etl/clear_state_inputs.py @@ -10,6 +10,7 @@ import boto3 from etl_utils.constants import CHANGELOG_NUMBER, WorkerKey from etl_utils.io import pkl_dumps_lz4 +from sds.epr.bulk_create.bulk_load_fanout import FANOUT from test_helpers.aws_session import aws_session from test_helpers.terraform import read_terraform_output @@ -37,6 +38,12 @@ def main(changelog_number, workspace): s3_client.put_object( Bucket=etl_bucket, Key=WorkerKey.LOAD, Body=EMPTY_JSON_DATA ) + for i in range(FANOUT): + s3_client.put_object( + Bucket=etl_bucket, + Key=f"{WorkerKey.LOAD}.{i}", + Body=pkl_dumps_lz4(EMPTY_JSON_DATA), + ) s3_client.delete_object(Bucket=etl_bucket, Key=CHANGELOG_NUMBER) if changelog_number: diff --git a/scripts/infrastructure/policies/integration-test-policy.json b/scripts/infrastructure/policies/integration-test-policy.json index e9eec5d36..69ebea83a 100644 --- a/scripts/infrastructure/policies/integration-test-policy.json +++ b/scripts/infrastructure/policies/integration-test-policy.json @@ -60,7 +60,8 @@ "Action": ["lambda:InvokeFunction"], "Resource": [ "arn:aws:lambda:*:${ACCOUNT_ID}:function:*--sds--notify", - "arn:aws:lambda:*:${ACCOUNT_ID}:function:*--sds--manual" + "arn:aws:lambda:*:${ACCOUNT_ID}:function:*--sds--manual", + "arn:aws:lambda:*:${ACCOUNT_ID}:function:*--sds--load_bulk" ] }, { diff --git a/src/api/tests/feature_tests/environment.py b/src/api/tests/feature_tests/environment.py index ae352eeaa..7b4106407 100644 --- a/src/api/tests/feature_tests/environment.py +++ b/src/api/tests/feature_tests/environment.py @@ -1,6 +1,8 @@ +import time from contextlib import nullcontext from pathlib import Path +import click from behave import use_fixture from behave.model import Feature, Scenario, Step from event.aws.client import dynamodb_client @@ -30,6 +32,8 @@ def before_all(context: Context): + clear_screen = context.config.userdata.get("clear_screen", "false") + context.clear_screen = clear_screen.lower() == "true" context.postman_collection = PostmanCollection() context.test_mode = TestMode.parse(config=context.config) context.table_name = LOCAL_TABLE_NAME @@ -114,6 +118,9 @@ def after_scenario(context: Context, scenario: Scenario): def after_feature(context: Context, feature: Feature): if context.postman_feature: context.postman_collection.item.append(context.postman_feature) + if context.clear_screen: + click.clear() + time.sleep(0.5) def after_all(context: Context): diff --git a/src/etl/sds/tests/_test_sds_etl_components.py b/src/etl/sds/tests/_test_sds_etl_components.py index 90fc63763..b9824a7b6 100644 --- a/src/etl/sds/tests/_test_sds_etl_components.py +++ b/src/etl/sds/tests/_test_sds_etl_components.py @@ -9,6 +9,11 @@ from domain.core.device_key import DeviceKeyType from domain.core.enum import Status from etl.clear_state_inputs import EMPTY_JSON_DATA, EMPTY_LDIF_DATA +from etl.sds.worker.extract.tests.test_extract_worker import ( + ANOTHER_GOOD_SDS_RECORD, + GOOD_SDS_RECORD, +) +from etl.sds.worker.load_bulk.tests._test_load_bulk_worker import MockDeviceRepository from etl_utils.constants import CHANGELOG_NUMBER, WorkerKey from etl_utils.io import pkl_dumps_lz4 from etl_utils.io.test.io_utils import pkl_loads_lz4 @@ -18,11 +23,6 @@ from mypy_boto3_stepfunctions.type_defs import StartSyncExecutionOutputTypeDef from etl.sds.tests.constants import BULK_TEST_CHANGELOG_NUMBER, EtlTestDataPath -from etl.sds.worker.extract.tests.test_extract_worker import ( - ANOTHER_GOOD_SDS_RECORD, - GOOD_SDS_RECORD, -) -from etl.sds.worker.load_bulk.tests._test_load_bulk_worker import MockDeviceRepository from test_helpers.dynamodb import clear_dynamodb_table from test_helpers.pytest_skips import long_running from test_helpers.terraform import read_terraform_output diff --git a/src/etl/sds/tests/changelog/_test_changelog_scenarios.py b/src/etl/sds/tests/changelog/_test_changelog_scenarios.py index 772743d76..ca45ee44f 100644 --- a/src/etl/sds/tests/changelog/_test_changelog_scenarios.py +++ b/src/etl/sds/tests/changelog/_test_changelog_scenarios.py @@ -6,11 +6,11 @@ from domain.repository.device_repository import DeviceRepository from domain.repository.keys import TableKey from domain.repository.marshall import unmarshall +from etl.sds.worker.load_bulk.tests._test_load_bulk_worker import MockDeviceRepository from etl_utils.io import pkl_load_lz4 from event.aws.client import dynamodb_client as get_dynamodb_client from mypy_boto3_s3 import S3Client -from etl.sds.worker.load_bulk.tests._test_load_bulk_worker import MockDeviceRepository from test_helpers.terraform import read_terraform_output from .conftest import ETL_BUCKET, parametrize_over_scenarios diff --git a/src/etl/sds/tests/etl_test_utils/ask_s3.py b/src/etl/sds/tests/etl_test_utils/ask_s3.py new file mode 100644 index 000000000..61d80a9ca --- /dev/null +++ b/src/etl/sds/tests/etl_test_utils/ask_s3.py @@ -0,0 +1,122 @@ +from collections.abc import Callable +from json import JSONDecodeError +from types import FunctionType + +from botocore.exceptions import ClientError +from etl.clear_state_inputs import EMPTY_JSON_DATA, EMPTY_LDIF_DATA +from etl_utils.constants import CHANGELOG_NUMBER, ETL_STATE_LOCK, WorkerKey +from event.json import json_loads +from mypy_boto3_dynamodb import DynamoDBClient +from mypy_boto3_s3 import S3Client + +from etl.sds.tests.etl_test_utils.etl_state import EtlConfig + +ALLOWED_EXCEPTIONS = (JSONDecodeError,) + + +def ask_s3( + s3_client: S3Client, bucket: str, key: str, question: Callable[[any], bool] = None +) -> bool: + result = True + try: + response = s3_client.get_object(Bucket=bucket, Key=key) + except ClientError: + result = False + + if result and question is not None: + data = response["Body"].read() + try: + result = question(data) + except ALLOWED_EXCEPTIONS: + result = False + return result + + +def ask_s3_prefix( + s3_client: S3Client, bucket: str, key_prefix: str, question: FunctionType = None +): + response = s3_client.list_objects(Bucket=bucket, Prefix=key_prefix) + keys = [item["Key"] for item in response.get("Contents", [])] + return any( + ask_s3(s3_client=s3_client, bucket=bucket, key=key, question=question) + for key in keys + ) + + +def was_trigger_key_deleted(s3_client, etl_config: EtlConfig): + return not ask_s3( + s3_client=s3_client, + bucket=etl_config.bucket, + key=etl_config.initial_trigger_key, + ) + + +def was_queue_history_created( + s3_client, etl_config: EtlConfig, expected_content: bytes +): + return ask_s3_prefix( + s3_client=s3_client, + bucket=etl_config.bucket, + key_prefix=f"{etl_config.queue_history_key_prefix}{etl_config.etl_type}", + question=lambda x: x == expected_content, + ) + + +def was_state_machine_history_created( + s3_client, etl_config: EtlConfig, expected_content: bytes +): + return ask_s3_prefix( + s3_client=s3_client, + bucket=etl_config.bucket, + key_prefix=f"{etl_config.state_machine_history_key_prefix}{etl_config.etl_type}", + question=lambda x: x == expected_content, + ) + + +def was_changelog_number_updated(s3_client, bucket, new_changelog_number): + return ask_s3( + s3_client=s3_client, + key=CHANGELOG_NUMBER, + bucket=bucket, + question=lambda x: json_loads(x) == new_changelog_number, + ) + + +def extract_is_empty(s3_client, bucket) -> bool: + return ask_s3( + s3_client=s3_client, + key=WorkerKey.EXTRACT, + bucket=bucket, + question=lambda x: x == EMPTY_LDIF_DATA, + ) + + +def transform_is_empty(s3_client, bucket) -> bool: + return ask_s3( + s3_client=s3_client, + key=WorkerKey.TRANSFORM, + bucket=bucket, + question=lambda x: x == EMPTY_JSON_DATA, + ) + + +def load_is_empty(s3_client, bucket) -> bool: + return ask_s3( + s3_client=s3_client, + key=WorkerKey.LOAD, + bucket=bucket, + question=lambda x: x == EMPTY_JSON_DATA, + ) + + +def was_etl_state_lock_removed(s3_client, bucket) -> bool: + return ask_s3( + s3_client=s3_client, + key=ETL_STATE_LOCK, + bucket=bucket, + ) + + +def database_isnt_empty(db_client: "DynamoDBClient", table_name: str): + count = db_client.scan(TableName=table_name, Limit=1, Select="COUNT")["Count"] + return count == 1 diff --git a/src/etl/sds/tests/etl_test_utils/etl_state.py b/src/etl/sds/tests/etl_test_utils/etl_state.py new file mode 100644 index 000000000..99c0551bb --- /dev/null +++ b/src/etl/sds/tests/etl_test_utils/etl_state.py @@ -0,0 +1,87 @@ +from collections import deque +from dataclasses import dataclass + +from etl_utils.constants import ( + CHANGELOG_NUMBER, + ETL_QUEUE_HISTORY, + ETL_STATE_LOCK, + ETL_STATE_MACHINE_HISTORY, + WorkerKey, +) +from etl_utils.io import pkl_dumps_lz4 +from mypy_boto3_s3 import S3Client +from sds.epr.bulk_create.bulk_load_fanout import FANOUT + +from test_helpers.terraform import read_terraform_output + +EMPTY_LDIF_DATA = b"" +EMPTY_JSON_DATA = deque() + + +@dataclass +class EtlConfig: + bucket: str + initial_trigger_key: str + queue_history_key_prefix: str + state_machine_history_key_prefix: str + etl_type: str + table_name: str + + +def get_etl_config(input_filename: str, etl_type: str = "") -> EtlConfig: + bulk_trigger_prefix = read_terraform_output("sds_etl.value.bulk_trigger_prefix") + return EtlConfig( + bucket=read_terraform_output("sds_etl.value.bucket"), + initial_trigger_key=f"{bulk_trigger_prefix}/{input_filename}", + queue_history_key_prefix=f"{ETL_QUEUE_HISTORY}/", + state_machine_history_key_prefix=f"{ETL_STATE_MACHINE_HISTORY}/", + etl_type=etl_type, + table_name=read_terraform_output("dynamodb_table_name.value"), + ) + + +def _delete_objects_by_prefix(s3_client: S3Client, bucket: str, key_prefix: str): + response = s3_client.list_objects(Bucket=bucket, Prefix=key_prefix) + for item in response.get("Contents", []): + s3_client.delete_object(Bucket=bucket, Key=item["Key"]) + + +def clear_etl_state(s3_client: S3Client, etl_config: EtlConfig): + + s3_client.put_object( + Bucket=etl_config.bucket, Key=WorkerKey.EXTRACT, Body=EMPTY_LDIF_DATA + ) + s3_client.put_object( + Bucket=etl_config.bucket, + Key=WorkerKey.TRANSFORM, + Body=pkl_dumps_lz4(EMPTY_JSON_DATA), + ) + s3_client.put_object( + Bucket=etl_config.bucket, + Key=WorkerKey.LOAD, + Body=pkl_dumps_lz4(EMPTY_JSON_DATA), + ) + for i in range(FANOUT): + s3_client.put_object( + Bucket=etl_config.bucket, + Key=f"{WorkerKey.LOAD}.{i}", + Body=pkl_dumps_lz4(EMPTY_JSON_DATA), + ) + s3_client.delete_object( + Bucket=etl_config.bucket, Key=etl_config.initial_trigger_key + ) + + _delete_objects_by_prefix( + s3_client=s3_client, + bucket=etl_config.bucket, + key_prefix=etl_config.queue_history_key_prefix, + ) + + _delete_objects_by_prefix( + s3_client=s3_client, + bucket=etl_config.bucket, + key_prefix=etl_config.state_machine_history_key_prefix, + ) + + s3_client.delete_object(Bucket=etl_config.bucket, Key=CHANGELOG_NUMBER) + s3_client.delete_object(Bucket=etl_config.bucket, Key=ETL_STATE_LOCK) diff --git a/src/etl/sds/tests/etl_test_utils/state_machine.py b/src/etl/sds/tests/etl_test_utils/state_machine.py new file mode 100644 index 000000000..d2ca05df6 --- /dev/null +++ b/src/etl/sds/tests/etl_test_utils/state_machine.py @@ -0,0 +1,49 @@ +import json +from typing import TYPE_CHECKING + +from etl_utils.trigger.model import StateMachineInput +from event.json import json_loads +from mypy_boto3_stepfunctions.type_defs import StartSyncExecutionOutputTypeDef + +from test_helpers.terraform import read_terraform_output + +if TYPE_CHECKING: + from mypy_boto3_stepfunctions import SFNClient + + +def execute_state_machine( + state_machine_input: StateMachineInput, step_functions_client: "SFNClient" +) -> StartSyncExecutionOutputTypeDef: + state_machine_arn = read_terraform_output("sds_etl.value.state_machine_arn") + name = state_machine_input.name + execution_response = step_functions_client.start_execution( + stateMachineArn=state_machine_arn, + name=name, + input=json.dumps(state_machine_input.dict()), + ) + + status = "RUNNING" + while status == "RUNNING": + response = step_functions_client.describe_execution( + executionArn=execution_response["executionArn"] + ) + status = response["status"] + + if response["status"] != "SUCCEEDED": + try: + cause = json_loads(response["cause"]) + error_message = cause["errorMessage"] + stack_trace = cause["stackTrace"] + except Exception: + error_message = response.get("cause", "no error message") + stack_trace = [] + + print( # noqa: T201 + "Error captured from state machine:\n", + error_message, + "\n", + *stack_trace, + ) + raise RuntimeError(response.get("error", "no error message")) + print("state machine response:", response) # noqa + return response diff --git a/src/etl/sds/trigger/bulk/tests/_test_bulk_trigger.py b/src/etl/sds/trigger/bulk/tests/_test_bulk_trigger.py deleted file mode 100644 index 292438a66..000000000 --- a/src/etl/sds/trigger/bulk/tests/_test_bulk_trigger.py +++ /dev/null @@ -1,122 +0,0 @@ -import time -from collections import deque -from functools import partial - -import boto3 -import pytest -from domain.core.device import DeviceType -from etl_utils.constants import CHANGELOG_NUMBER, ETL_STATE_LOCK, WorkerKey -from etl_utils.io.test.io_utils import pkl_loads_lz4 -from event.aws.client import dynamodb_client -from event.json import json_loads - -from etl.sds.worker.extract.tests.test_extract_worker import GOOD_SDS_RECORD -from etl.sds.worker.load_bulk.tests._test_load_bulk_worker import MockDeviceRepository -from test_helpers.dynamodb import clear_dynamodb_table -from test_helpers.s3 import ( - _ask_s3, - _ask_s3_prefix, - _set_etl_content, - _set_etl_content_config, -) - -EXPECTED_CHANGELOG_NUMBER = 123 - - -@pytest.mark.timeout(20) -@pytest.mark.integration -def test_bulk_trigger(): - # Where the state is located - bucket_config = _set_etl_content_config() - table_name = bucket_config["table_name"] - - client = dynamodb_client() - repository = MockDeviceRepository(table_name=table_name, dynamodb_client=client) - - s3_client = boto3.client("s3") - ask_s3 = partial(_ask_s3, s3_client=s3_client, bucket=bucket_config["etl_bucket"]) - ask_s3_prefix = partial( - _ask_s3_prefix, s3_client=s3_client, bucket=bucket_config["etl_bucket"] - ) - - was_trigger_key_deleted = lambda: not ask_s3( - key=bucket_config["initial_trigger_key"] - ) - was_queue_history_created = lambda: ask_s3_prefix( - key_prefix=f"{bucket_config['queue_history_key_prefix']}/bulk", - question=lambda x: x == GOOD_SDS_RECORD.encode(), - ) - was_state_machine_history_created = lambda: ask_s3_prefix( - key_prefix=f"{bucket_config['state_machine_history_key_prefix']}/bulk", - question=lambda x: x == GOOD_SDS_RECORD.encode(), - ) - was_changelog_number_updated = lambda: ask_s3( - key=CHANGELOG_NUMBER, - question=lambda x: json_loads(x) == EXPECTED_CHANGELOG_NUMBER, - ) - was_state_machine_successful = ( - lambda: ask_s3( - key=WorkerKey.EXTRACT, - question=lambda x: x == b"", - ) - and ask_s3( - key=WorkerKey.TRANSFORM, - question=lambda x: pkl_loads_lz4(x) == deque(), - ) - and ask_s3( - key=WorkerKey.LOAD, - question=lambda x: pkl_loads_lz4(x) == deque(), - ) - and repository.count(by=DeviceType.PRODUCT) > 0 - ) - was_etl_state_lock_removed = lambda: not ask_s3(key=ETL_STATE_LOCK) - - _set_etl_content(s3_client=s3_client, bucket_config=bucket_config) - s3_client.delete_object(Bucket=bucket_config["etl_bucket"], Key=CHANGELOG_NUMBER) - s3_client.delete_object(Bucket=bucket_config["etl_bucket"], Key=ETL_STATE_LOCK) - clear_dynamodb_table(client=client, table_name=bucket_config["table_name"]) - - # Trigger the bulk load - s3_client.put_object( - Bucket=bucket_config["etl_bucket"], - Key=bucket_config["initial_trigger_key"], - Body=GOOD_SDS_RECORD.encode(), - ) - - trigger_key_deleted = False - queue_history_created = False - state_machine_history_created = False - changelog_number_updated = False - state_machine_successful = False - etl_state_lock_removed = False - while not all( - ( - trigger_key_deleted, - queue_history_created, - state_machine_history_created, - changelog_number_updated, - state_machine_successful, - etl_state_lock_removed, - ) - ): - time.sleep(5) - trigger_key_deleted = trigger_key_deleted or was_trigger_key_deleted() - queue_history_created = queue_history_created or was_queue_history_created() - state_machine_history_created = ( - state_machine_history_created or was_state_machine_history_created() - ) - changelog_number_updated = ( - changelog_number_updated or was_changelog_number_updated() - ) - state_machine_successful = ( - state_machine_successful or was_state_machine_successful() - ) - etl_state_lock_removed = etl_state_lock_removed or was_etl_state_lock_removed() - - # Confirm the final state - assert trigger_key_deleted - assert queue_history_created - assert state_machine_history_created - assert changelog_number_updated - assert state_machine_successful - assert etl_state_lock_removed diff --git a/src/etl/sds/trigger/bulk/tests/test_bulk_trigger.py b/src/etl/sds/trigger/bulk/tests/test_bulk_trigger.py new file mode 100644 index 000000000..3011dac02 --- /dev/null +++ b/src/etl/sds/trigger/bulk/tests/test_bulk_trigger.py @@ -0,0 +1,131 @@ +import time +from functools import partial + +import boto3 +import pytest +from event.aws.client import dynamodb_client + +from etl.sds.tests.etl_test_utils.ask_s3 import ( + database_isnt_empty as _database_isnt_empty, +) +from etl.sds.tests.etl_test_utils.ask_s3 import extract_is_empty as _extract_is_empty +from etl.sds.tests.etl_test_utils.ask_s3 import load_is_empty as _load_is_empty +from etl.sds.tests.etl_test_utils.ask_s3 import ( + transform_is_empty as _transform_is_empty, +) +from etl.sds.tests.etl_test_utils.ask_s3 import ( + was_changelog_number_updated as _was_changelog_number_updated, +) +from etl.sds.tests.etl_test_utils.ask_s3 import ( + was_etl_state_lock_removed as _was_etl_state_lock_removed, +) +from etl.sds.tests.etl_test_utils.ask_s3 import ( + was_queue_history_created as _was_queue_history_created, +) +from etl.sds.tests.etl_test_utils.ask_s3 import ( + was_state_machine_history_created as _was_state_machine_history_created, +) +from etl.sds.tests.etl_test_utils.ask_s3 import ( + was_trigger_key_deleted as _was_trigger_key_deleted, +) +from etl.sds.tests.etl_test_utils.etl_state import clear_etl_state, get_etl_config +from etl.sds.worker.bulk.tests.test_bulk_e2e import PATH_TO_STAGE_DATA + +EXPECTED_CHANGELOG_NUMBER = 123 + + +def message(x): + print(x) # noqa + + +@pytest.mark.timeout(40) +@pytest.mark.integration +def test_bulk_trigger(): + # Prerequisites + with open(PATH_TO_STAGE_DATA / "0.extract_input.ldif") as f: + input_data = f.read().encode() + + etl_config = get_etl_config(f"{EXPECTED_CHANGELOG_NUMBER}.ldif", etl_type="bulk") + db_client = dynamodb_client() + s3_client = boto3.client("s3") + clear_etl_state(s3_client=s3_client, etl_config=etl_config) + + # Define questions + was_trigger_key_deleted = partial( + _was_trigger_key_deleted, s3_client=s3_client, etl_config=etl_config + ) + was_queue_history_created = partial( + _was_queue_history_created, + s3_client=s3_client, + etl_config=etl_config, + expected_content=input_data, + ) + was_state_machine_history_created = partial( + _was_state_machine_history_created, + s3_client=s3_client, + etl_config=etl_config, + expected_content=input_data, + ) + was_changelog_number_updated = partial( + _was_changelog_number_updated, + s3_client=s3_client, + bucket=etl_config.bucket, + new_changelog_number=EXPECTED_CHANGELOG_NUMBER, + ) + extract_is_empty = partial( + _extract_is_empty, s3_client=s3_client, bucket=etl_config.bucket + ) + transform_is_empty = partial( + _transform_is_empty, s3_client=s3_client, bucket=etl_config.bucket + ) + load_is_empty = partial( + _load_is_empty, s3_client=s3_client, bucket=etl_config.bucket + ) + was_state_lock_removed = partial( + _was_etl_state_lock_removed, s3_client=s3_client, bucket=etl_config.bucket + ) + database_isnt_empty = partial( + _database_isnt_empty, db_client=db_client, table_name=etl_config.table_name + ) + + # Trigger the bulk load + s3_client.put_object( + Bucket=etl_config.bucket, Key=etl_config.initial_trigger_key, Body=input_data + ) + + # Sign-off through the expected lifecycle of the bulk ETL + while not was_trigger_key_deleted(): + time.sleep(1) + message("Trigger key deleted") + + while not was_queue_history_created(): + time.sleep(1) + message("Queue history created") + + while not was_state_machine_history_created(): + time.sleep(1) + message("State machine history created") + + while not was_changelog_number_updated(): + time.sleep(1) + message("Changelog number updated") + + while not extract_is_empty(): + time.sleep(1) + message("Extract's input data is now in empty state") + + while not transform_is_empty(): + time.sleep(1) + message("Transform's input data is now in empty state") + + while not database_isnt_empty(): + time.sleep(1) + message("Database isn't empty") + + assert load_is_empty() + message("Load's input data is now in empty state") + + while not was_state_lock_removed(): + time.sleep(1) + message("State lock has been removed") + time.sleep(10) # Grace period for Step Function to complete diff --git a/src/etl/sds/trigger/manual/tests/_test_manual_trigger.py b/src/etl/sds/trigger/manual/tests/test_manual_trigger.py similarity index 79% rename from src/etl/sds/trigger/manual/tests/_test_manual_trigger.py rename to src/etl/sds/trigger/manual/tests/test_manual_trigger.py index 41cd9497c..51178ad97 100644 --- a/src/etl/sds/trigger/manual/tests/_test_manual_trigger.py +++ b/src/etl/sds/trigger/manual/tests/test_manual_trigger.py @@ -8,8 +8,8 @@ from event.json import json_loads from mypy_boto3_lambda.type_defs import InvocationResponseTypeDef -from etl.sds.worker.extract.tests.test_extract_worker import GOOD_SDS_RECORD -from test_helpers.s3 import _set_etl_content, _set_etl_content_config +from etl.sds.tests.etl_test_utils.etl_state import clear_etl_state, get_etl_config +from etl.sds.worker.bulk.tests.test_bulk_e2e import PATH_TO_STAGE_DATA from test_helpers.terraform import read_terraform_output TEST_DATA_NAME = "123.ldif" @@ -28,27 +28,32 @@ ], ) def test_manual_trigger(history_object): + time.sleep(10) # Grace period for any previous Step Functions to complete + # Where the state is located - bucket_config = _set_etl_content_config() + etl_config = get_etl_config(f"{EXPECTED_CHANGELOG_NUMBER}.ldif") manual_trigger_arn = read_terraform_output("manual_trigger_arn.value") expected = history_object.split(".") expected_prefix = ".".join(expected[:3]) # Set some questions s3_client = boto3.client("s3") - _set_etl_content(s3_client=s3_client, bucket_config=bucket_config) + clear_etl_state(s3_client=s3_client, etl_config=etl_config) # Assert history folder empty state_machine_bucket_contents = s3_client.list_objects( - Bucket=bucket_config["etl_bucket"], Prefix=f"{ETL_STATE_MACHINE_HISTORY}/" + Bucket=etl_config.bucket, Prefix=f"{ETL_STATE_MACHINE_HISTORY}/" ) assert "Contents" not in state_machine_bucket_contents + with open(PATH_TO_STAGE_DATA / "0.extract_input.ldif") as f: + input_data = f.read().encode() + # set up test (add file to history bucket) s3_client.put_object( - Bucket=bucket_config["etl_bucket"], + Bucket=etl_config.bucket, Key=f"{ETL_STATE_MACHINE_HISTORY}/{history_object}", - Body=GOOD_SDS_RECORD, + Body=input_data, ) # manually trigger @@ -78,7 +83,7 @@ def test_manual_trigger(history_object): ) # Ensure the latest execution was the rerun expected state_machine_history_files = s3_client.list_objects( - Bucket=bucket_config["etl_bucket"], Prefix=f"{ETL_STATE_MACHINE_HISTORY}/" + Bucket=etl_config.bucket, Prefix=f"{ETL_STATE_MACHINE_HISTORY}/" ) item_count = 0 for item in state_machine_history_files.get("Contents", []): diff --git a/src/etl/sds/worker/extract/__init__.py b/src/etl/sds/worker/archive/extract/__init__.py similarity index 100% rename from src/etl/sds/worker/extract/__init__.py rename to src/etl/sds/worker/archive/extract/__init__.py diff --git a/src/etl/sds/worker/extract/extract.py b/src/etl/sds/worker/archive/extract/extract.py similarity index 100% rename from src/etl/sds/worker/extract/extract.py rename to src/etl/sds/worker/archive/extract/extract.py diff --git a/src/etl/sds/worker/extract/make/make.py b/src/etl/sds/worker/archive/extract/make/make.py similarity index 100% rename from src/etl/sds/worker/extract/make/make.py rename to src/etl/sds/worker/archive/extract/make/make.py diff --git a/src/etl/sds/worker/extract/tests/test_extract_worker.py b/src/etl/sds/worker/archive/extract/tests/_test_extract_worker.py similarity index 100% rename from src/etl/sds/worker/extract/tests/test_extract_worker.py rename to src/etl/sds/worker/archive/extract/tests/_test_extract_worker.py diff --git a/src/etl/sds/worker/load_bulk/__init__.py b/src/etl/sds/worker/archive/load_bulk/__init__.py similarity index 100% rename from src/etl/sds/worker/load_bulk/__init__.py rename to src/etl/sds/worker/archive/load_bulk/__init__.py diff --git a/src/etl/sds/worker/load_bulk/load_bulk.py b/src/etl/sds/worker/archive/load_bulk/load_bulk.py similarity index 100% rename from src/etl/sds/worker/load_bulk/load_bulk.py rename to src/etl/sds/worker/archive/load_bulk/load_bulk.py diff --git a/src/etl/sds/worker/load_bulk/make/make.py b/src/etl/sds/worker/archive/load_bulk/make/make.py similarity index 100% rename from src/etl/sds/worker/load_bulk/make/make.py rename to src/etl/sds/worker/archive/load_bulk/make/make.py diff --git a/src/etl/sds/worker/load_bulk/tests/_test_load_bulk_worker.py b/src/etl/sds/worker/archive/load_bulk/tests/_test_load_bulk_worker.py similarity index 100% rename from src/etl/sds/worker/load_bulk/tests/_test_load_bulk_worker.py rename to src/etl/sds/worker/archive/load_bulk/tests/_test_load_bulk_worker.py diff --git a/src/etl/sds/worker/load_bulk_reduce/load_bulk_reduce.py b/src/etl/sds/worker/archive/load_bulk_reduce/load_bulk_reduce.py similarity index 100% rename from src/etl/sds/worker/load_bulk_reduce/load_bulk_reduce.py rename to src/etl/sds/worker/archive/load_bulk_reduce/load_bulk_reduce.py diff --git a/src/etl/sds/worker/load_bulk_reduce/make/make.py b/src/etl/sds/worker/archive/load_bulk_reduce/make/make.py similarity index 100% rename from src/etl/sds/worker/load_bulk_reduce/make/make.py rename to src/etl/sds/worker/archive/load_bulk_reduce/make/make.py diff --git a/src/etl/sds/worker/load_bulk_reduce/tests/_test_load_bulk_reduce.py b/src/etl/sds/worker/archive/load_bulk_reduce/tests/_test_load_bulk_reduce.py similarity index 100% rename from src/etl/sds/worker/load_bulk_reduce/tests/_test_load_bulk_reduce.py rename to src/etl/sds/worker/archive/load_bulk_reduce/tests/_test_load_bulk_reduce.py diff --git a/src/etl/sds/worker/load_update/__init__.py b/src/etl/sds/worker/archive/load_update/__init__.py similarity index 100% rename from src/etl/sds/worker/load_update/__init__.py rename to src/etl/sds/worker/archive/load_update/__init__.py diff --git a/src/etl/sds/worker/load_update/load_update.py b/src/etl/sds/worker/archive/load_update/load_update.py similarity index 100% rename from src/etl/sds/worker/load_update/load_update.py rename to src/etl/sds/worker/archive/load_update/load_update.py diff --git a/src/etl/sds/worker/load_update/make/make.py b/src/etl/sds/worker/archive/load_update/make/make.py similarity index 100% rename from src/etl/sds/worker/load_update/make/make.py rename to src/etl/sds/worker/archive/load_update/make/make.py diff --git a/src/etl/sds/worker/load_update/tests/_test_load_update_worker.py b/src/etl/sds/worker/archive/load_update/tests/_test_load_update_worker.py similarity index 100% rename from src/etl/sds/worker/load_update/tests/_test_load_update_worker.py rename to src/etl/sds/worker/archive/load_update/tests/_test_load_update_worker.py index 12e971460..daf873093 100644 --- a/src/etl/sds/worker/load_update/tests/_test_load_update_worker.py +++ b/src/etl/sds/worker/archive/load_update/tests/_test_load_update_worker.py @@ -5,12 +5,6 @@ import pytest from domain.core.device import Device -from etl_utils.constants import WorkerKey -from etl_utils.io import pkl_dumps_lz4 -from etl_utils.io.test.io_utils import pkl_loads_lz4 -from moto import mock_aws -from mypy_boto3_s3 import S3Client - from etl.sds.worker.load_bulk.tests._test_load_bulk_worker import ( BUCKET_NAME, TABLE_NAME, @@ -18,6 +12,12 @@ device_factory, ) from etl.sds.worker.transform_update.utils import export_events +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from moto import mock_aws +from mypy_boto3_s3 import S3Client + from test_helpers.dynamodb import mock_table diff --git a/src/etl/sds/worker/transform_bulk/__init__.py b/src/etl/sds/worker/archive/transform_bulk/__init__.py similarity index 100% rename from src/etl/sds/worker/transform_bulk/__init__.py rename to src/etl/sds/worker/archive/transform_bulk/__init__.py diff --git a/src/etl/sds/worker/transform_bulk/make/make.py b/src/etl/sds/worker/archive/transform_bulk/make/make.py similarity index 100% rename from src/etl/sds/worker/transform_bulk/make/make.py rename to src/etl/sds/worker/archive/transform_bulk/make/make.py diff --git a/src/etl/sds/worker/transform_bulk/tests/_test_transform_bulk_worker.py b/src/etl/sds/worker/archive/transform_bulk/tests/_test_transform_bulk_worker.py similarity index 99% rename from src/etl/sds/worker/transform_bulk/tests/_test_transform_bulk_worker.py rename to src/etl/sds/worker/archive/transform_bulk/tests/_test_transform_bulk_worker.py index 49f573699..14cfebee7 100644 --- a/src/etl/sds/worker/transform_bulk/tests/_test_transform_bulk_worker.py +++ b/src/etl/sds/worker/archive/transform_bulk/tests/_test_transform_bulk_worker.py @@ -8,6 +8,7 @@ import pytest from botocore.exceptions import ClientError +from etl.sds.worker.transform_bulk.utils import smart_open_if_exists from etl_utils.constants import WorkerKey from etl_utils.io import pkl_dumps_lz4 from etl_utils.io.test.io_utils import pkl_loads_lz4 @@ -15,8 +16,6 @@ from moto import mock_aws from mypy_boto3_s3 import S3Client -from etl.sds.worker.transform_bulk.utils import smart_open_if_exists - BUCKET_NAME = "my-bucket" TABLE_NAME = "my-table" diff --git a/src/etl/sds/worker/transform_bulk/transform_bulk.py b/src/etl/sds/worker/archive/transform_bulk/transform_bulk.py similarity index 99% rename from src/etl/sds/worker/transform_bulk/transform_bulk.py rename to src/etl/sds/worker/archive/transform_bulk/transform_bulk.py index 6a8c9d979..62a504acc 100644 --- a/src/etl/sds/worker/transform_bulk/transform_bulk.py +++ b/src/etl/sds/worker/archive/transform_bulk/transform_bulk.py @@ -5,6 +5,7 @@ import boto3 from domain.core.device import Device from domain.core.event import ExportedEventTypeDef +from etl.sds.worker.transform_bulk.utils import smart_open_if_exists from etl_utils.constants import WorkerKey from etl_utils.io import pkl_dump_lz4, pkl_dumps_lz4, pkl_load_lz4 from etl_utils.smart_open import smart_open @@ -14,8 +15,6 @@ from event.environment import BaseEnvironment from sds.cpm_translation import translate -from etl.sds.worker.transform_bulk.utils import smart_open_if_exists - if TYPE_CHECKING: from mypy_boto3_s3 import S3Client diff --git a/src/etl/sds/worker/transform_bulk/utils.py b/src/etl/sds/worker/archive/transform_bulk/utils.py similarity index 100% rename from src/etl/sds/worker/transform_bulk/utils.py rename to src/etl/sds/worker/archive/transform_bulk/utils.py diff --git a/src/etl/sds/worker/transform_update/__init__.py b/src/etl/sds/worker/archive/transform_update/__init__.py similarity index 100% rename from src/etl/sds/worker/transform_update/__init__.py rename to src/etl/sds/worker/archive/transform_update/__init__.py diff --git a/src/etl/sds/worker/transform_update/make/make.py b/src/etl/sds/worker/archive/transform_update/make/make.py similarity index 100% rename from src/etl/sds/worker/transform_update/make/make.py rename to src/etl/sds/worker/archive/transform_update/make/make.py diff --git a/src/etl/sds/worker/transform_update/tests/_test_transform_update_worker.py b/src/etl/sds/worker/archive/transform_update/tests/_test_transform_update_worker.py similarity index 99% rename from src/etl/sds/worker/transform_update/tests/_test_transform_update_worker.py rename to src/etl/sds/worker/archive/transform_update/tests/_test_transform_update_worker.py index bc30891a4..cb52715e3 100644 --- a/src/etl/sds/worker/transform_update/tests/_test_transform_update_worker.py +++ b/src/etl/sds/worker/archive/transform_update/tests/_test_transform_update_worker.py @@ -9,12 +9,6 @@ import pytest from domain.core.device import DeviceType from domain.core.root import Root -from etl_utils.constants import WorkerKey -from etl_utils.io import pkl_dumps_lz4 -from etl_utils.io.test.io_utils import pkl_loads_lz4 -from moto import mock_aws -from mypy_boto3_s3 import S3Client - from etl.sds.worker.transform_bulk.tests._test_transform_bulk_worker import ( BAD_SDS_RECORD_AS_JSON, BUCKET_NAME, @@ -24,6 +18,11 @@ TABLE_NAME, ) from etl.sds.worker.transform_update.utils import export_events +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from moto import mock_aws +from mypy_boto3_s3 import S3Client @pytest.fixture diff --git a/src/etl/sds/worker/transform_update/transform_update.py b/src/etl/sds/worker/archive/transform_update/transform_update.py similarity index 99% rename from src/etl/sds/worker/transform_update/transform_update.py rename to src/etl/sds/worker/archive/transform_update/transform_update.py index c78628168..7d63a4e03 100644 --- a/src/etl/sds/worker/transform_update/transform_update.py +++ b/src/etl/sds/worker/archive/transform_update/transform_update.py @@ -5,6 +5,7 @@ import boto3 from domain.core.event import ExportedEventTypeDef from domain.repository.device_repository import DeviceRepository +from etl.sds.worker.transform_update.utils import export_events from etl_utils.constants import WorkerKey from etl_utils.io import pkl_dump_lz4, pkl_load_lz4 from etl_utils.smart_open import smart_open @@ -15,8 +16,6 @@ from event.environment import BaseEnvironment from sds.cpm_translation import translate -from etl.sds.worker.transform_update.utils import export_events - if TYPE_CHECKING: from mypy_boto3_s3 import S3Client diff --git a/src/etl/sds/worker/transform_update/utils.py b/src/etl/sds/worker/archive/transform_update/utils.py similarity index 100% rename from src/etl/sds/worker/transform_update/utils.py rename to src/etl/sds/worker/archive/transform_update/utils.py diff --git a/src/etl/sds/worker/bulk/extract_bulk/__init__.py b/src/etl/sds/worker/bulk/extract_bulk/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/bulk/extract_bulk/extract_bulk.py b/src/etl/sds/worker/bulk/extract_bulk/extract_bulk.py new file mode 100644 index 000000000..33e2d4c00 --- /dev/null +++ b/src/etl/sds/worker/bulk/extract_bulk/extract_bulk.py @@ -0,0 +1,78 @@ +import json +from collections import deque +from dataclasses import asdict +from io import BytesIO +from typing import TYPE_CHECKING + +import boto3 +from etl_utils.constants import WorkerKey +from etl_utils.io import EtlEncoder, pkl_dump_lz4 +from etl_utils.ldif.ldif import filter_and_group_ldif_from_s3_by_property, parse_ldif +from etl_utils.worker.action import apply_action +from etl_utils.worker.model import WorkerActionResponse, WorkerEnvironment +from etl_utils.worker.worker_step_chain import execute_step_chain +from event.json import json_loads +from nhs_context_logging import log_action +from sds.domain.constants import FILTER_TERMS +from sds.domain.parse import parse_sds_record + +_log_action_without_inputs = lambda function: log_action(log_args=[], log_result=False)( + function +) + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + + +S3_CLIENT = boto3.client("s3") +ENVIRONMENT = WorkerEnvironment.build() + + +@_log_action_without_inputs +def _read(s3_client: "S3Client", s3_input_path: str) -> deque[tuple[dict]]: + filtered_ldif_by_group = filter_and_group_ldif_from_s3_by_property( + s3_path=s3_input_path, + filter_terms=FILTER_TERMS, + group_field="nhsMhsPartyKey", + s3_client=s3_client, + ) + return deque( + tuple(parse_ldif(file_opener=BytesIO, path_or_data=filtered_ldif)) + for filtered_ldif in filtered_ldif_by_group + ) + + +def extract( + s3_client: "S3Client", s3_input_path: str, s3_output_path: str, max_records: int +) -> WorkerActionResponse: + unprocessed_records = _read(s3_client=s3_client, s3_input_path=s3_input_path) + processed_records = deque([]) + + exception = apply_action( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + action=lambda record: [[parse_sds_record(*r).dict() for r in record]], + record_serializer=lambda dns_and_records: json_loads( + json.dumps([r[1] for r in dns_and_records], cls=EtlEncoder) + ), + ) + + return WorkerActionResponse( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + exception=exception, + s3_input_path=s3_input_path, + s3_output_path=s3_output_path, + ) + + +def handler(event, context): + response = execute_step_chain( + action=extract, + s3_client=S3_CLIENT, + s3_input_path=ENVIRONMENT.s3_path(WorkerKey.EXTRACT), + s3_output_path=ENVIRONMENT.s3_path(WorkerKey.TRANSFORM), + unprocessed_dumper=lambda **kwargs: None, + processed_dumper=pkl_dump_lz4, + ) + return asdict(response) diff --git a/src/etl/sds/worker/bulk/extract_bulk/make/make.py b/src/etl/sds/worker/bulk/extract_bulk/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/bulk/extract_bulk/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/bulk/extract_bulk/tests/test_extract_bulk_worker.py b/src/etl/sds/worker/bulk/extract_bulk/tests/test_extract_bulk_worker.py new file mode 100644 index 000000000..0a6c45689 --- /dev/null +++ b/src/etl/sds/worker/bulk/extract_bulk/tests/test_extract_bulk_worker.py @@ -0,0 +1,85 @@ +import json +import os +from typing import Callable +from unittest import mock + +import pytest +from etl_utils.constants import LDIF_RECORD_DELIMITER, WorkerKey +from etl_utils.io import EtlEncoder, pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from etl_utils.worker.model import WorkerEnvironment +from event.json import json_load, json_loads +from moto import mock_aws +from mypy_boto3_s3 import S3Client + +from etl.sds.worker.bulk.tests.test_bulk_e2e import PATH_TO_STAGE_DATA + +BUCKET_NAME = "my-bucket" + + +@pytest.fixture +def mock_s3_client(): + with mock_aws(), mock.patch.dict( + os.environ, + {"ETL_BUCKET": BUCKET_NAME, "AWS_DEFAULT_REGION": "us-east-1"}, + clear=True, + ): + from etl.sds.worker.bulk.extract_bulk import extract_bulk + + extract_bulk.ENVIRONMENT = WorkerEnvironment.build() + extract_bulk.S3_CLIENT.create_bucket(Bucket=BUCKET_NAME) + yield extract_bulk.S3_CLIENT + + +@pytest.fixture +def put_object(mock_s3_client: S3Client): + return lambda key, body: ( + mock_s3_client.put_object(Bucket=BUCKET_NAME, Key=key, Body=body) + ) + + +@pytest.fixture +def get_object(mock_s3_client: S3Client) -> bytes: + return lambda key: ( + mock_s3_client.get_object(Bucket=BUCKET_NAME, Key=key)["Body"].read() + ) + + +def _split_ldif(data: str) -> list[str]: + return list(filter(bool, data.split(LDIF_RECORD_DELIMITER))) + + +def test_extract_worker_pass( + put_object: Callable[[str], None], get_object: Callable[[str], bytes] +): + from etl.sds.worker.bulk.extract_bulk import extract_bulk + + # Initial state + with open(PATH_TO_STAGE_DATA / "0.extract_input.ldif") as f: + input_data = f.read() + + put_object(key=WorkerKey.EXTRACT, body=input_data) + put_object(key=WorkerKey.TRANSFORM, body=pkl_dumps_lz4({})) + + # Execute the extract worker + response = extract_bulk.handler(event={}, context=None) + assert response == { + "stage_name": "extract", + "processed_records": 2, + "unprocessed_records": 0, + "error_message": None, + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.EXTRACT).decode() + output_data = get_object(key=WorkerKey.TRANSFORM) + n_final_unprocessed = len(_split_ldif(final_unprocessed_data)) + + with open(PATH_TO_STAGE_DATA / "1.extract_output.json") as f: + expected_output_data = json_load(f) + + assert ( + json_loads(json.dumps(pkl_loads_lz4(output_data), cls=EtlEncoder)) + == expected_output_data + ) + assert n_final_unprocessed == 0 diff --git a/src/etl/sds/worker/bulk/load_bulk/__init__.py b/src/etl/sds/worker/bulk/load_bulk/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/bulk/load_bulk/load_bulk.py b/src/etl/sds/worker/bulk/load_bulk/load_bulk.py new file mode 100644 index 000000000..76f8d016d --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk/load_bulk.py @@ -0,0 +1,62 @@ +from collections import deque +from dataclasses import asdict +from typing import TYPE_CHECKING + +from etl_utils.io import pkl_dump_lz4, pkl_load_lz4 +from etl_utils.smart_open import smart_open +from etl_utils.worker.action import apply_action +from etl_utils.worker.model import WorkerActionResponse, WorkerEvent +from etl_utils.worker.worker_step_chain import execute_step_chain +from sds.worker.load import LoadWorkerCache + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + +CACHE = LoadWorkerCache() + + +class BulkLoadWorkerEvent(WorkerEvent): + s3_input_path: str + + +def load( + s3_client: "S3Client", s3_input_path: str, s3_output_path: str, max_records: int +) -> WorkerActionResponse: + """ + For bulk, the transformed data is ready to pass to the repository.write_bulk + so nothing to do here other than load and buffer the data from + 'unprocessed_records' to 'processed_records' + """ + with smart_open(s3_path=s3_input_path, s3_client=s3_client) as f: + unprocessed_records: deque[dict] = pkl_load_lz4(f) + processed_records = deque() + + exception = apply_action( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + action=lambda record: record, + max_records=max_records, + ) + + with smart_open(s3_path=s3_input_path, s3_client=s3_client) as f: + return WorkerActionResponse( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + s3_input_path=s3_input_path, + exception=exception, + ) + + +def handler(event: dict, context): + worker_event = BulkLoadWorkerEvent(**event) + max_records = worker_event.max_records or CACHE.MAX_RECORDS + response = execute_step_chain( + action=load, + s3_client=CACHE.S3_CLIENT, + s3_input_path=worker_event.s3_input_path, + s3_output_path=None, + unprocessed_dumper=pkl_dump_lz4, + processed_dumper=CACHE.REPOSITORY.write, + max_records=max_records, + ) + return asdict(response) diff --git a/src/etl/sds/worker/bulk/load_bulk/make/make.py b/src/etl/sds/worker/bulk/load_bulk/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/bulk/load_bulk/tests/edge_cases/.gitkeep b/src/etl/sds/worker/bulk/load_bulk/tests/edge_cases/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/bulk/load_bulk/tests/test_load_bulk_worker.py b/src/etl/sds/worker/bulk/load_bulk/tests/test_load_bulk_worker.py new file mode 100644 index 000000000..f8c3d0262 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk/tests/test_load_bulk_worker.py @@ -0,0 +1,254 @@ +import json +import os +from collections import deque +from itertools import chain +from pathlib import Path +from typing import Callable +from unittest import mock + +import boto3 +import pytest +from domain.core.cpm_product.v1 import CpmProduct +from domain.core.device.v1 import Device +from domain.core.device_reference_data.v1 import DeviceReferenceData +from domain.core.product_team.v1 import ProductTeam +from domain.repository.cpm_product_repository.v1 import CpmProductRepository +from domain.repository.device_reference_data_repository.v1 import ( + DeviceReferenceDataRepository, +) +from domain.repository.device_repository.v1 import DeviceRepository +from domain.repository.product_team_repository.v1 import ProductTeamRepository +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4, pkl_load_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from event.json import json_load +from moto import mock_aws +from mypy_boto3_s3 import S3Client +from sds.epr.bulk_create.bulk_load_fanout import FANOUT +from sds.epr.constants import AS_DEVICE_SUFFIX, MHS_DEVICE_SUFFIX + +from etl.sds.worker.bulk.tests.test_bulk_e2e import PATH_TO_STAGE_DATA +from test_helpers.dynamodb import mock_table +from test_helpers.terraform import read_terraform_output + +BUCKET_NAME = "my-bucket" +TABLE_NAME = "my-table" +PATH_TO_HERE = Path(__file__).parent + + +@pytest.fixture +def mock_s3_client(): + with mock_aws(), mock.patch.dict( + os.environ, + { + "ETL_BUCKET": BUCKET_NAME, + "TABLE_NAME": TABLE_NAME, + "AWS_DEFAULT_REGION": "us-east-1", + }, + clear=True, + ): + from etl.sds.worker.bulk.load_bulk import load_bulk + + load_bulk.CACHE.S3_CLIENT.create_bucket(Bucket=BUCKET_NAME) + yield load_bulk.CACHE.S3_CLIENT + + +@pytest.fixture +def put_object(mock_s3_client: S3Client): + return lambda key, body: ( + mock_s3_client.put_object(Bucket=BUCKET_NAME, Key=key, Body=body) + ) + + +@pytest.fixture +def get_object(mock_s3_client: S3Client) -> bytes: + return lambda key: ( + mock_s3_client.get_object(Bucket=BUCKET_NAME, Key=key)["Body"].read() + ) + + +def test_load_worker_pass( + put_object: Callable[[str], None], get_object: Callable[[str], bytes] +): + from etl.sds.worker.bulk.load_bulk import load_bulk + + # Initial state + for i in range(FANOUT): + with open(PATH_TO_STAGE_DATA / f"3.load_fanout_output.{i}.json") as f: + input_data = json_load(f) + + put_object( + key=f"{WorkerKey.LOAD}.{i}", + body=pkl_dumps_lz4(deque(input_data)), + ) + + # Execute the load worker + with mock_table(TABLE_NAME) as dynamodb_client: + load_bulk.CACHE.REPOSITORY.client = dynamodb_client + + responses = [] + for i in range(FANOUT): + response = load_bulk.handler( + event={"s3_input_path": f"s3://{BUCKET_NAME}/{WorkerKey.LOAD}.{i}"}, + context=None, + ) + responses.append(response) + + # Final state + final_unprocessed_data = pkl_loads_lz4( + get_object(key=f"{WorkerKey.LOAD}.{i}") + ) + assert final_unprocessed_data == deque([]) + + assert responses == [ + { + "stage_name": "load", + "processed_records": 10, + "unprocessed_records": 0, + "error_message": None, + } + ] * (FANOUT - 1) + [ + { + "stage_name": "load", + "processed_records": 7, + "unprocessed_records": 0, + "error_message": None, + } + ] + product_team_repo = ProductTeamRepository( + table_name=TABLE_NAME, dynamodb_client=dynamodb_client + ) + (product_team,) = product_team_repo.search() + product_team_by_key = product_team_repo.read("EPR-LSP04") + product_team_by_id = product_team_repo.read( + "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + ) + assert product_team == product_team_by_key + assert product_team == product_team_by_id + + product_repo = CpmProductRepository( + table_name=TABLE_NAME, dynamodb_client=dynamodb_client + ) + products = product_repo.search(product_team_id=product_team.id) + product_team_a = product_repo.read( + product_team_id=product_team.id, id="AAA-111111" + ) + product_team_b = product_repo.read( + product_team_id=product_team.id, id="BBB-111111" + ) + assert products == [product_team_b, product_team_a] + + device_repo = DeviceRepository( + table_name=TABLE_NAME, dynamodb_client=dynamodb_client + ) + devices = list( + chain.from_iterable( + device_repo.search( + product_team_id=product_team.id, product_id=product.id + ) + for product in products + ) + ) + mhs_devices = [d for d in devices if d.name.endswith(MHS_DEVICE_SUFFIX)] + as_devices = [d for d in devices if d.name.endswith(AS_DEVICE_SUFFIX)] + assert len(devices) == len(mhs_devices) + len(as_devices) + assert len(mhs_devices) == 2 + assert len(as_devices) == 4 + + device_ref_data_repo = DeviceReferenceDataRepository( + table_name=TABLE_NAME, dynamodb_client=dynamodb_client + ) + device_ref_datas = list( + chain.from_iterable( + device_ref_data_repo.search( + product_team_id=product_team.id, product_id=product.id + ) + for product in products + ) + ) + assert len(device_ref_datas) == 4 + + with open(PATH_TO_STAGE_DATA / "2.transform_output.json") as f: + input_data: list[dict[str, dict]] = json_load(f) + + (input_product_team,) = ( + ProductTeam(**data) + for item in input_data + for object_type_name, data in item.items() + if object_type_name == "ProductTeam" + ) + + input_products = sorted( + ( + CpmProduct(**data) + for item in input_data + for object_type_name, data in item.items() + if object_type_name == "CpmProduct" + ), + key=lambda product: str(product.id), + ) + + input_devices = sorted( + ( + Device(**data) + for item in input_data + for object_type_name, data in item.items() + if object_type_name == "Device" + ), + key=lambda device: (str(device.product_id), device.id), + ) + + input_device_ref_data = sorted( + ( + DeviceReferenceData(**data) + for item in input_data + for object_type_name, data in item.items() + if object_type_name == "DeviceReferenceData" + ), + key=lambda device_ref_data: ( + str(device_ref_data.product_id), + device_ref_data.id, + ), + ) + + assert product_team == input_product_team + assert products == input_products + assert devices == input_devices + assert device_ref_datas == input_device_ref_data + + +@pytest.mark.integration +@pytest.mark.parametrize("path", (PATH_TO_HERE / "edge_cases").iterdir()) +def test_load_worker_edge_cases(path: Path): + if path.name == ".gitkeep": + pytest.skip() + + s3_client = boto3.client("s3") + lambda_client = boto3.client("lambda") + bucket = read_terraform_output("sds_etl.value.bucket") + lambda_name = read_terraform_output("sds_etl.value.bulk_load_lambda_arn") + + with open(path) as f: + s3_client.put_object( + Key=f"{WorkerKey.LOAD}.0", + Bucket=bucket, + body=pkl_dumps_lz4(deque(json_load(f))), + ) + + response = lambda_client.invoke( + FunctionName=lambda_name, + Payload=json.dumps({"s3_input_path": f"s3://{BUCKET_NAME}/{WorkerKey.LOAD}.0"}), + ) + assert json_load(response["Payload"]) == { + "stage_name": "load", + "processed_records": 10, + "unprocessed_records": 0, + "error_message": None, + } + + # Final state + _final_unprocessed_data = s3_client.get_object( + Key=f"{WorkerKey.LOAD}.0", Bucket=bucket + )["Body"] + final_unprocessed_data = pkl_load_lz4(_final_unprocessed_data) + assert final_unprocessed_data == deque([]) diff --git a/src/etl/sds/worker/bulk/load_bulk_fanout/__init__.py b/src/etl/sds/worker/bulk/load_bulk_fanout/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/bulk/load_bulk_fanout/load_bulk_fanout.py b/src/etl/sds/worker/bulk/load_bulk_fanout/load_bulk_fanout.py new file mode 100644 index 000000000..888ffe312 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk_fanout/load_bulk_fanout.py @@ -0,0 +1,155 @@ +from collections import deque +from dataclasses import asdict +from itertools import batched +from types import FunctionType +from typing import TYPE_CHECKING + +import boto3 +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dump_lz4, pkl_load_lz4 +from etl_utils.smart_open import smart_open +from etl_utils.worker.action import apply_action +from etl_utils.worker.model import WorkerActionResponse +from etl_utils.worker.steps import ( + execute_action, + save_processed_records, + save_unprocessed_records, +) +from etl_utils.worker.worker_step_chain import ( + _log_action_without_inputs, + _render_response, + log_exception, +) +from event.environment import BaseEnvironment +from event.step_chain import StepChain +from sds.epr.bulk_create.bulk_load_fanout import FANOUT, calculate_batch_size +from sds.epr.bulk_create.bulk_repository import BulkRepository + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + + +class TransformWorkerEnvironment(BaseEnvironment): + ETL_BUCKET: str + + def s3_path(self, key) -> str: + return f"s3://{self.ETL_BUCKET}/{key}" + + +ENVIRONMENT = TransformWorkerEnvironment.build() +S3_CLIENT = boto3.client("s3") + + +def execute_step_chain( + action: FunctionType, + s3_client, + s3_input_path: str, + s3_output_path: str, + unprocessed_dumper: FunctionType, + processed_dumper: FunctionType, + max_records: int = None, + **kwargs, +) -> list[dict]: + # Run the main action chain + action_chain = StepChain( + step_chain=[execute_action], step_decorators=[_log_action_without_inputs] + ) + action_chain.run( + init=(action, s3_client, s3_input_path, s3_output_path, max_records, kwargs) + ) + if isinstance(action_chain.result, Exception): + log_exception(action_chain.result) + + # Save the action chain results if there were no unhandled (fatal) exceptions + count_unprocessed_records = None + count_processed_records = None + save_chain_response = None + + worker_response = [] + if isinstance(action_chain.result, WorkerActionResponse): + if isinstance(action_chain.result.exception, Exception): + log_exception(action_chain.result.exception) + + count_unprocessed_records = len(action_chain.result.unprocessed_records) + + batch_size = calculate_batch_size( + sequence=action_chain.result.processed_records, n_batches=FANOUT + ) + for i, batch in enumerate( + batched(action_chain.result.processed_records, n=batch_size) + ): + count_processed_records = len(batch) + _action_response = WorkerActionResponse( + unprocessed_records=action_chain.result.unprocessed_records, + s3_input_path=action_chain.result.s3_input_path, + processed_records=deque(batch), + s3_output_path=ENVIRONMENT.s3_path(f"{WorkerKey.LOAD}.{i}"), + exception=action_chain.result.exception, + ) + + save_chain = StepChain( + step_chain=[save_unprocessed_records, save_processed_records], + step_decorators=[_log_action_without_inputs], + ) + save_chain.run( + init=( + _action_response, + s3_client, + unprocessed_dumper, + processed_dumper, + ) + ) + save_chain_response = save_chain.result + + if isinstance(save_chain.result, Exception): + log_exception(save_chain.result) + + # Summarise the outcome of action_chain and step_chain + worker_response_item = _render_response( + action_name=action.__name__, + action_chain_response=_action_response, + save_chain_response=save_chain_response, + count_unprocessed_records=count_unprocessed_records, + count_processed_records=count_processed_records, + ) + _response = asdict(worker_response_item) + _response["s3_input_path"] = ENVIRONMENT.s3_path(f"{WorkerKey.LOAD}.{i}") + worker_response.append(_response) + return worker_response + + +def load_bulk_fanout( + s3_client: "S3Client", s3_input_path: str, s3_output_path: str, max_records: int +) -> WorkerActionResponse: + with smart_open(s3_path=s3_input_path, s3_client=s3_client) as f: + unprocessed_records: deque[dict] = pkl_load_lz4(f) + processed_records = deque() + + exception = apply_action( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + action=lambda record: BulkRepository( + None, None + ).generate_transaction_statements(record), + max_records=max_records, + ) + + return WorkerActionResponse( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + s3_input_path=s3_input_path, + s3_output_path=s3_output_path, + exception=exception, + ) + + +def handler(event: dict, context): + return execute_step_chain( + action=load_bulk_fanout, + s3_client=S3_CLIENT, + s3_input_path=ENVIRONMENT.s3_path(WorkerKey.LOAD), + s3_output_path=None, + unprocessed_dumper=pkl_dump_lz4, + processed_dumper=pkl_dump_lz4, + max_records=None, + ) diff --git a/src/etl/sds/worker/bulk/load_bulk_fanout/make/make.py b/src/etl/sds/worker/bulk/load_bulk_fanout/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk_fanout/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/bulk/load_bulk_fanout/tests/test_load_bulk_fanout_worker.py b/src/etl/sds/worker/bulk/load_bulk_fanout/tests/test_load_bulk_fanout_worker.py new file mode 100644 index 000000000..a2a2a5322 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk_fanout/tests/test_load_bulk_fanout_worker.py @@ -0,0 +1,166 @@ +import os +from collections import deque +from itertools import batched +from pathlib import Path +from typing import Callable +from unittest import mock + +import pytest +from domain.core.cpm_product.v1 import CpmProduct +from domain.core.device.v1 import Device +from domain.core.device_reference_data.v1 import DeviceReferenceData +from domain.core.product_team.v1 import ProductTeam +from domain.repository.compression import pkl_loads_gzip +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from event.json import json_load +from moto import mock_aws +from mypy_boto3_s3 import S3Client +from sds.epr.bulk_create.bulk_load_fanout import ( + FANOUT, + calculate_batch_size, + count_indexes, +) + +from etl.sds.worker.bulk.tests.test_bulk_e2e import PATH_TO_STAGE_DATA + +BUCKET_NAME = "my-bucket" +TABLE_NAME = "my-table" +PATH_TO_HERE = Path(__file__).parent + + +@pytest.fixture +def mock_s3_client(): + with ( + mock_aws(), + mock.patch.dict( + os.environ, + { + "ETL_BUCKET": BUCKET_NAME, + "TABLE_NAME": TABLE_NAME, + "AWS_DEFAULT_REGION": "us-east-1", + }, + clear=True, + ), + ): + from etl.sds.worker.bulk.load_bulk import load_bulk + + load_bulk.CACHE.S3_CLIENT.create_bucket(Bucket=BUCKET_NAME) + yield load_bulk.CACHE.S3_CLIENT + + +@pytest.fixture +def put_object(mock_s3_client: S3Client): + return lambda key, body: ( + mock_s3_client.put_object(Bucket=BUCKET_NAME, Key=key, Body=body) + ) + + +@pytest.fixture +def get_object(mock_s3_client: S3Client) -> bytes: + return lambda key: ( + mock_s3_client.get_object(Bucket=BUCKET_NAME, Key=key)["Body"].read() + ) + + +def decompress(obj: dict) -> dict: + tags = obj["PutRequest"]["Item"].get("tags") + if tags: + tags["S"] = [pkl_loads_gzip(tag) for tag in pkl_loads_gzip(tags["S"])] + + questionnaire_responses = obj["PutRequest"]["Item"].get( + "questionnaire_responses", {} + ) + if questionnaire_responses.get("S"): + questionnaire_responses["S"] = pkl_loads_gzip(questionnaire_responses["S"]) + + return obj + + +@pytest.mark.parametrize( + ("n_batches", "sequence_length", "expected_batch_size", "expected_n_batches"), + ((4, 100, 25, 4), (3, 100, 34, 3), (16, 30, 2, 15)), +) +def test_calculate_batch_size_general( + n_batches: int, + sequence_length: int, + expected_batch_size: int, + expected_n_batches: int, +): + n_batches = n_batches + sequence = list(range(sequence_length)) + batch_size = calculate_batch_size(sequence, n_batches) + assert batch_size == expected_batch_size + + batches = list(batched(sequence, batch_size)) + assert len(batches) == expected_n_batches + + +def test_load_worker_fanout( + put_object: Callable[[str], None], get_object: Callable[[str], bytes] +): + from etl.sds.worker.bulk.load_bulk_fanout import load_bulk_fanout + + # Initial state + with open(PATH_TO_STAGE_DATA / "2.transform_output.json") as f: + input_data: list[dict[str, dict]] = json_load(f) + + put_object( + key=WorkerKey.LOAD, + body=pkl_dumps_lz4(deque(input_data)), + ) + + # Execute the load worker + responses = load_bulk_fanout.handler(event={}, context=None) + + assert len(responses) == FANOUT + assert responses == [ + { + "stage_name": "load_bulk_fanout", + "processed_records": 10, + "unprocessed_records": 0, + "s3_input_path": f"s3://my-bucket/input--load/unprocessed.{i}", + "error_message": None, + } + for i in range(0, FANOUT - 1) + ] + [ + { + "stage_name": "load_bulk_fanout", + "processed_records": 7, + "unprocessed_records": 0, + "s3_input_path": f"s3://my-bucket/input--load/unprocessed.{FANOUT - 1}", + "error_message": None, + }, + ] + + # Final state + final_processed_data = pkl_loads_lz4(get_object(key=WorkerKey.LOAD)) + assert final_processed_data == deque([]) + total_size = 0 + for i in range(10): + final_unprocessed_data = pkl_loads_lz4(get_object(key=f"{WorkerKey.LOAD}.{i}")) + assert isinstance(final_unprocessed_data, deque) + total_size += len(final_unprocessed_data) + + with open(PATH_TO_STAGE_DATA / f"3.load_fanout_output.{i}.json") as f: + expected_final_data: list[dict[str, dict]] = json_load(f) + assert list(map(decompress, final_unprocessed_data)) == list( + map(decompress, expected_final_data) + ) + + expected_total_size = 0 + for obj in input_data: + ((obj_name, obj_data),) = obj.items() + match obj_name: + case "Device": + obj = Device(**obj_data) + case "DeviceReferenceData": + obj = DeviceReferenceData(**obj_data) + case "ProductTeam": + obj = ProductTeam(**obj_data) + case "CpmProduct": + obj = CpmProduct(**obj_data) + expected_total_size += count_indexes(obj) + + assert total_size == expected_total_size diff --git a/src/etl/sds/worker/bulk/load_bulk_reduce/load_bulk_reduce.py b/src/etl/sds/worker/bulk/load_bulk_reduce/load_bulk_reduce.py new file mode 100644 index 000000000..9aecf6c94 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk_reduce/load_bulk_reduce.py @@ -0,0 +1,21 @@ +from dataclasses import asdict + +from etl_utils.worker.model import WorkerResponse + + +def combine_error_messages(*args) -> str | None: + non_null_error_messages = filter(lambda x: isinstance(x, str), args) + combined_error_message = "\n--- NEXT ERROR ---\n".join(non_null_error_messages) + return combined_error_message or None + + +def handler(event: list[dict], context): + combined_response = WorkerResponse(stage_name="load") + for _response in event: + response = WorkerResponse(**_response) + combined_response.processed_records += response.processed_records + combined_response.unprocessed_records += response.unprocessed_records + combined_response.error_message = combine_error_messages( + combined_response.error_message, response.error_message + ) + return asdict(combined_response) diff --git a/src/etl/sds/worker/bulk/load_bulk_reduce/make/make.py b/src/etl/sds/worker/bulk/load_bulk_reduce/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk_reduce/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/bulk/load_bulk_reduce/tests/test_load_bulk_reduce.py b/src/etl/sds/worker/bulk/load_bulk_reduce/tests/test_load_bulk_reduce.py new file mode 100644 index 000000000..ff5ee7167 --- /dev/null +++ b/src/etl/sds/worker/bulk/load_bulk_reduce/tests/test_load_bulk_reduce.py @@ -0,0 +1,55 @@ +from etl.sds.worker.bulk.load_bulk_reduce.load_bulk_reduce import ( + combine_error_messages, + handler, +) + + +def test_combine_error_messages(): + assert ( + combine_error_messages("foo", None, None, "bar", None) + == "foo\n--- NEXT ERROR ---\nbar" + ) + + +def test_combine_error_messages_all_None(): + assert combine_error_messages(None, None, None) is None + + +def test_bulk_load_reduce_handler_empty(): + assert handler(event=[], context=None) == { + "stage_name": "load", + "processed_records": 0, + "unprocessed_records": 0, + "error_message": None, + } + + +def test_bulk_load_reduce_handler_combined(): + assert handler( + event=[ + { + "stage_name": "foo", + "processed_records": 12, + "unprocessed_records": 3, + "error_message": "foo", + }, + { + "stage_name": "bar", + "processed_records": 2, + "unprocessed_records": 1, + "error_message": "bar", + }, + { + "stage_name": "bar", + "processed_records": 13, + "unprocessed_records": 5, + "error_message": None, + }, + ], + context=None, + ) == { + "stage_name": "load", + "processed_records": 27, + "unprocessed_records": 9, + "error_message": "foo\n--- NEXT ERROR ---\nbar", + } diff --git a/src/etl/sds/worker/bulk/tests/stage_data/0.extract_input.ldif b/src/etl/sds/worker/bulk/tests/stage_data/0.extract_input.ldif new file mode 100644 index 000000000..6ee78efd6 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/0.extract_input.ldif @@ -0,0 +1,165 @@ +dn: uniqueIdentifier=00000000000a,ou=Services,o=nhs +objectClass: nhsMhs +objectClass: top +nhsApproverURP: myApprover +nhsDateApproved: 20010101010101 +nhsDateDNSApproved: 20010101010101 +nhsDateRequested: 20010101010101 +nhsDNSApprover: myApprover +nhsIDCode: AAA +nhsMHSAckRequested: never +nhsMhsCPAId: 00000000000a +nhsMHSDuplicateElimination: never +nhsMHSEndPoint: https://test.C3O9X.nhs.uk/ +nhsMhsFQDN: test.C3O9X.nhs.uk +nhsMHsIN: READ_PRACTITIONER_ROLE_R4_V001 +nhsMhsIPAddress: 0.0.0.0 +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey:: QUFBLTExMTExMSA= +nhsMHsSN: urn:nhs:names:services:ers +nhsMhsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001 +nhsProductKey: 111 +nhsProductName: My AAA Product +nhsProductVersion: 2005.02 +nhsRequestorURP: myRequestor +uniqueIdentifier: 00000000000a +nhsContractPropertyTemplateKey: 14 +nhsEPInteractionType: FHIR +nhsMHSIsAuthenticated: none + +dn: uniqueIdentifier=000000000001,ou=Services,o=nhs +objectClass: nhsAS +objectClass: top +nhsApproverURP: myApprover +nhsAsClient: AAA +nhsAsSvcIA: urn:nhs:names:services:pds:QUPA_IN040000UK01 +nhsAsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001 +nhsDateApproved: 20010101010101 +nhsDateRequested: 20010101010101 +nhsIDCode: AAA +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey: AAA-111111 +nhsProductKey: 111 +nhsProductName: My AAA Product +nhsProductVersion: 2005.02 +nhsRequestorURP: myRequestor +nhsTempUid: 111 +uniqueIdentifier: 000000000001 + +dn: uniqueIdentifier=000000000002,ou=Services,o=nhs +objectClass: nhsAS +objectClass: top +nhsApproverURP: myApprover +nhsAsClient: BBB +nhsAsSvcIA: urn:nhs:names:services:pds:QUPA_IN040000UK02 +nhsAsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002 +nhsAsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003 +nhsDateApproved: 20020202020202 +nhsDateRequested: 20020202020202 +nhsIDCode: BBB +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey: BBB-111111 +nhsProductKey: 222 +nhsProductName: My BBB Product +nhsProductVersion: 2005.02 +nhsRequestorURP: myRequestor +nhsTempUid: 222 +uniqueIdentifier: 000000000002 + +dn: uniqueIdentifier=00000000000b,ou=Services,o=nhs +objectClass: nhsMhs +objectClass: top +nhsApproverURP: myApprover +nhsDateApproved: 20020202020202 +nhsDateDNSApproved: 20020202020202 +nhsDateRequested: 20020202020202 +nhsDNSApprover: myApprover +nhsIDCode: BBB +nhsMHSAckRequested: never +nhsMhsCPAId: 00000000000b +nhsMHSDuplicateElimination: never +nhsMHSEndPoint: https://test.C3O9X.nhs.uk/ +nhsMhsFQDN: test.C3O9X.nhs.uk +nhsMHsIN: READ_PRACTITIONER_ROLE_R4_V002 +nhsMhsIPAddress: 0.0.0.0 +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey: BBB-111111 +nhsMHsSN: urn:nhs:names:services:ers +nhsMhsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002 +nhsProductKey: 111 +nhsProductName: My BBB Product +nhsProductVersion: 2005.02 +nhsRequestorURP: myRequestor +uniqueIdentifier: 00000000000b +nhsContractPropertyTemplateKey: 14 +nhsEPInteractionType: FHIR +nhsMHSIsAuthenticated: none + +dn: uniqueIdentifier=000000000003,ou=Services,o=nhs +objectClass: nhsAS +objectClass: top +nhsApproverURP: myApprover +nhsAsClient: BBB +nhsAsSvcIA: urn:nhs:names:services:pds:QUPA_IN040000UK03 +nhsAsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002 +nhsAsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003 +nhsDateApproved: 20030303030303 +nhsDateRequested: 20030303030303 +nhsIDCode: BBB +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey: BBB-111111 +nhsProductKey: 333 +nhsProductName: My BBB Product +nhsProductVersion: 2005.02 +nhsRequestorURP: myRequestor +nhsTempUid: 333 +uniqueIdentifier: 000000000003 + +dn: uniqueIdentifier=000000000004,ou=Services,o=nhs +objectClass: nhsAS +objectClass: top +nhsApproverURP: myApprover +nhsAsClient: AAA +nhsAsSvcIA: urn:nhs:names:services:pds:QUPA_IN040000UK04 +nhsAsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001 +nhsDateApproved: 20040404040404 +nhsDateRequested: 20040404040404 +nhsIDCode: AAA +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey: AAA-111111 +nhsProductKey: 444 +nhsProductName: My AAA Product +nhsProductVersion: 2005.02 +nhsRequestorURP: myRequestor +nhsTempUid: 444 +uniqueIdentifier: 000000000004 + + +dn: uniqueIdentifier=00000000000c,ou=Services,o=nhs +objectClass: nhsMhs +objectClass: top +nhsApproverURP: myApprover +nhsDateApproved: 20020202020202 +nhsDateDNSApproved: 20020202020202 +nhsDateRequested: 20020202020202 +nhsDNSApprover: myApprover +nhsIDCode: BBB +nhsMHSAckRequested: never +nhsMhsCPAId: 00000000000c +nhsMHSDuplicateElimination: never +nhsMHSEndPoint: https://test.C3O9X.nhs.uk/ +nhsMhsFQDN: test.C3O9X.nhs.uk +nhsMHsIN: READ_PRACTITIONER_ROLE_R4_V002 +nhsMhsIPAddress: 0.0.0.0 +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey: BBB-111111 +nhsMHsSN: urn:nhs:names:services:ers +nhsMhsSvcIA: urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003 +nhsProductKey: 111 +nhsProductName: My BBB Product +nhsProductVersion: 2005.02 +nhsRequestorURP: myRequestor +uniqueIdentifier: 00000000000c +nhsContractPropertyTemplateKey: 14 +nhsEPInteractionType: FHIR +nhsMHSIsAuthenticated: none diff --git a/src/etl/sds/worker/bulk/tests/stage_data/1.extract_output.json b/src/etl/sds/worker/bulk/tests/stage_data/1.extract_output.json new file mode 100644 index 000000000..e97a7ad78 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/1.extract_output.json @@ -0,0 +1,209 @@ +[ + [ + { + "change_type": "add", + "nhs_approver_urp": "myApprover", + "nhs_contract_property_template_key": "14", + "nhs_date_approved": "20010101010101", + "nhs_date_dns_approved": "20010101010101", + "nhs_date_requested": "20010101010101", + "nhs_dns_approver": "myApprover", + "nhs_ep_interaction_type": "fhir", + "nhs_id_code": "AAA", + "nhs_mhs_ack_requested": "never", + "nhs_mhs_actor": null, + "nhs_mhs_cpa_id": "00000000000a", + "nhs_mhs_duplicate_elimination": "never", + "nhs_mhs_end_point": "https://test.C3O9X.nhs.uk/", + "nhs_mhs_fqdn": "test.C3O9X.nhs.uk", + "nhs_mhs_in": "READ_PRACTITIONER_ROLE_R4_V001", + "nhs_mhs_ip_address": "0.0.0.0", + "nhs_mhs_is_authenticated": "none", + "nhs_mhs_manufacturer_org": "LSP04", + "nhs_mhs_party_key": "AAA-111111", + "nhs_mhs_persist_duration": null, + "nhs_mhs_retries": null, + "nhs_mhs_retry_interval": null, + "nhs_mhs_service_description": null, + "nhs_mhs_sn": "urn:nhs:names:services:ers", + "nhs_mhs_svc_ia": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001", + "nhs_mhs_sync_reply_mode": null, + "nhs_product_key": "111", + "nhs_product_name": "My AAA Product", + "nhs_product_version": "2005.02", + "nhs_requestor_urp": "myRequestor", + "object_class": "nhsMhs", + "unique_identifier": "00000000000a" + }, + { + "change_type": "add", + "description": null, + "nhs_approver_urp": "myApprover", + "nhs_as_acf": null, + "nhs_as_category_bag": null, + "nhs_as_client": ["AAA"], + "nhs_as_svc_ia": [ + "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001", + "urn:nhs:names:services:pds:QUPA_IN040000UK01" + ], + "nhs_date_approved": "20010101010101", + "nhs_date_requested": "20010101010101", + "nhs_id_code": "AAA", + "nhs_mhs_manufacturer_org": "LSP04", + "nhs_mhs_party_key": "AAA-111111", + "nhs_product_key": "111", + "nhs_product_name": "My AAA Product", + "nhs_product_version": "2005.02", + "nhs_requestor_urp": "myRequestor", + "nhs_temp_uid": "111", + "object_class": "nhsAS", + "unique_identifier": "000000000001" + }, + { + "change_type": "add", + "description": null, + "nhs_approver_urp": "myApprover", + "nhs_as_acf": null, + "nhs_as_category_bag": null, + "nhs_as_client": ["AAA"], + "nhs_as_svc_ia": [ + "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001", + "urn:nhs:names:services:pds:QUPA_IN040000UK04" + ], + "nhs_date_approved": "20040404040404", + "nhs_date_requested": "20040404040404", + "nhs_id_code": "AAA", + "nhs_mhs_manufacturer_org": "LSP04", + "nhs_mhs_party_key": "AAA-111111", + "nhs_product_key": "444", + "nhs_product_name": "My AAA Product", + "nhs_product_version": "2005.02", + "nhs_requestor_urp": "myRequestor", + "nhs_temp_uid": "444", + "object_class": "nhsAS", + "unique_identifier": "000000000004" + } + ], + [ + { + "change_type": "add", + "description": null, + "nhs_approver_urp": "myApprover", + "nhs_as_acf": null, + "nhs_as_category_bag": null, + "nhs_as_client": ["BBB"], + "nhs_as_svc_ia": [ + "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002", + "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003", + "urn:nhs:names:services:pds:QUPA_IN040000UK02" + ], + "nhs_date_approved": "20020202020202", + "nhs_date_requested": "20020202020202", + "nhs_id_code": "BBB", + "nhs_mhs_manufacturer_org": "LSP04", + "nhs_mhs_party_key": "BBB-111111", + "nhs_product_key": "222", + "nhs_product_name": "My BBB Product", + "nhs_product_version": "2005.02", + "nhs_requestor_urp": "myRequestor", + "nhs_temp_uid": "222", + "object_class": "nhsAS", + "unique_identifier": "000000000002" + }, + { + "change_type": "add", + "nhs_approver_urp": "myApprover", + "nhs_contract_property_template_key": "14", + "nhs_date_approved": "20020202020202", + "nhs_date_dns_approved": "20020202020202", + "nhs_date_requested": "20020202020202", + "nhs_dns_approver": "myApprover", + "nhs_ep_interaction_type": "fhir", + "nhs_id_code": "BBB", + "nhs_mhs_ack_requested": "never", + "nhs_mhs_actor": null, + "nhs_mhs_cpa_id": "00000000000b", + "nhs_mhs_duplicate_elimination": "never", + "nhs_mhs_end_point": "https://test.C3O9X.nhs.uk/", + "nhs_mhs_fqdn": "test.C3O9X.nhs.uk", + "nhs_mhs_in": "READ_PRACTITIONER_ROLE_R4_V002", + "nhs_mhs_ip_address": "0.0.0.0", + "nhs_mhs_is_authenticated": "none", + "nhs_mhs_manufacturer_org": "LSP04", + "nhs_mhs_party_key": "BBB-111111", + "nhs_mhs_persist_duration": null, + "nhs_mhs_retries": null, + "nhs_mhs_retry_interval": null, + "nhs_mhs_service_description": null, + "nhs_mhs_sn": "urn:nhs:names:services:ers", + "nhs_mhs_svc_ia": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002", + "nhs_mhs_sync_reply_mode": null, + "nhs_product_key": "111", + "nhs_product_name": "My BBB Product", + "nhs_product_version": "2005.02", + "nhs_requestor_urp": "myRequestor", + "object_class": "nhsMhs", + "unique_identifier": "00000000000b" + }, + { + "change_type": "add", + "description": null, + "nhs_approver_urp": "myApprover", + "nhs_as_acf": null, + "nhs_as_category_bag": null, + "nhs_as_client": ["BBB"], + "nhs_as_svc_ia": [ + "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002", + "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003", + "urn:nhs:names:services:pds:QUPA_IN040000UK03" + ], + "nhs_date_approved": "20030303030303", + "nhs_date_requested": "20030303030303", + "nhs_id_code": "BBB", + "nhs_mhs_manufacturer_org": "LSP04", + "nhs_mhs_party_key": "BBB-111111", + "nhs_product_key": "333", + "nhs_product_name": "My BBB Product", + "nhs_product_version": "2005.02", + "nhs_requestor_urp": "myRequestor", + "nhs_temp_uid": "333", + "object_class": "nhsAS", + "unique_identifier": "000000000003" + }, + { + "change_type": "add", + "nhs_approver_urp": "myApprover", + "nhs_contract_property_template_key": "14", + "nhs_date_approved": "20020202020202", + "nhs_date_dns_approved": "20020202020202", + "nhs_date_requested": "20020202020202", + "nhs_dns_approver": "myApprover", + "nhs_ep_interaction_type": "fhir", + "nhs_id_code": "BBB", + "nhs_mhs_ack_requested": "never", + "nhs_mhs_actor": null, + "nhs_mhs_cpa_id": "00000000000c", + "nhs_mhs_duplicate_elimination": "never", + "nhs_mhs_end_point": "https://test.C3O9X.nhs.uk/", + "nhs_mhs_fqdn": "test.C3O9X.nhs.uk", + "nhs_mhs_in": "READ_PRACTITIONER_ROLE_R4_V002", + "nhs_mhs_ip_address": "0.0.0.0", + "nhs_mhs_is_authenticated": "none", + "nhs_mhs_manufacturer_org": "LSP04", + "nhs_mhs_party_key": "BBB-111111", + "nhs_mhs_persist_duration": null, + "nhs_mhs_retries": null, + "nhs_mhs_retry_interval": null, + "nhs_mhs_service_description": null, + "nhs_mhs_sn": "urn:nhs:names:services:ers", + "nhs_mhs_svc_ia": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003", + "nhs_mhs_sync_reply_mode": null, + "nhs_product_key": "111", + "nhs_product_name": "My BBB Product", + "nhs_product_version": "2005.02", + "nhs_requestor_urp": "myRequestor", + "object_class": "nhsMhs", + "unique_identifier": "00000000000c" + } + ] +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/2.transform_output.json b/src/etl/sds/worker/bulk/tests/stage_data/2.transform_output.json new file mode 100644 index 000000000..a282c0529 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/2.transform_output.json @@ -0,0 +1,945 @@ +[ + { + "ProductTeam": { + "id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "name": "LSP04 (EPR)", + "ods_code": "LSP04", + "status": "active", + "created_on": "2024-11-20T10:54:19.001479+00:00", + "updated_on": null, + "deleted_on": null, + "keys": [{ "key_type": "epr_id", "key_value": "EPR-LSP04" }] + } + }, + { + "CpmProduct": { + "id": "P.VNT-MLW", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "name": "My AAA Product", + "ods_code": "LSP04", + "status": "active", + "created_on": "2024-11-20T10:54:19.001733+00:00", + "updated_on": "2024-11-20T10:54:19.002057+00:00", + "deleted_on": null, + "keys": [{ "key_type": "party_key", "key_value": "AAA-111111" }] + } + }, + { + "DeviceReferenceData": { + "id": "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6", + "name": "AAA-111111 - MHS Message Sets", + "product_id": "P.VNT-MLW", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "status": "active", + "questionnaire_responses": { + "spine_mhs_message_sets/1": [ + { + "id": "5e4cab5e-bcbd-47f6-afa2-7a2b86853ca5", + "questionnaire_name": "spine_mhs_message_sets", + "questionnaire_version": "1", + "data": { + "MHS IN": "READ_PRACTITIONER_ROLE_R4_V001", + "MHS SN": "urn:nhs:names:services:ers", + "Interaction ID": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001" + }, + "created_on": "2024-11-20T10:54:19.000224+00:00" + } + ] + }, + "created_on": "2024-11-20T10:54:19.002130+00:00", + "updated_on": "2024-11-20T10:54:19.002249+00:00", + "deleted_on": null + } + }, + { + "DeviceReferenceData": { + "id": "d3d0e6b8-8277-4849-8e8d-5cb035af5536", + "name": "AAA-111111 - AS Additional Interactions", + "product_id": "P.VNT-MLW", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "status": "active", + "questionnaire_responses": { + "spine_as_additional_interactions/1": [ + { + "id": "170711a5-2e77-453b-a04f-4723cf8e9f87", + "questionnaire_name": "spine_as_additional_interactions", + "questionnaire_version": "1", + "data": { + "Interaction ID": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001" + }, + "created_on": "2024-11-20T10:54:19.000557+00:00" + }, + { + "id": "cb431ce5-5de2-42cd-9430-2e0b0ad91639", + "questionnaire_name": "spine_as_additional_interactions", + "questionnaire_version": "1", + "data": { + "Interaction ID": "urn:nhs:names:services:pds:QUPA_IN040000UK01" + }, + "created_on": "2024-11-20T10:54:19.000872+00:00" + }, + { + "id": "36fa5061-f9b7-4980-8cf7-abafdb25f670", + "questionnaire_name": "spine_as_additional_interactions", + "questionnaire_version": "1", + "data": { + "Interaction ID": "urn:nhs:names:services:pds:QUPA_IN040000UK04" + }, + "created_on": "2024-11-20T10:54:19.001186+00:00" + } + ] + }, + "created_on": "2024-11-20T10:54:19.003795+00:00", + "updated_on": "2024-11-20T10:54:19.004000+00:00", + "deleted_on": null + } + }, + { + "Device": { + "id": "192133bc-7077-4163-9387-9856969dd412", + "name": "AAA-111111 - Message Handling System", + "status": "active", + "product_id": "P.VNT-MLW", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "created_on": "2024-11-20T10:54:19.002315+00:00", + "updated_on": "2024-11-20T10:54:19.003736+00:00", + "deleted_on": null, + "keys": [{ "key_type": "cpa_id", "key_value": "00000000000a" }], + "tags": [ + [["nhs_mhs_party_key", "aaa-111111"]], + [ + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ] + ], + [["nhs_id_code", "aaa"]], + [ + ["nhs_id_code", "aaa"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_mhs_party_key", "aaa-111111"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ] + ], + [ + ["nhs_id_code", "aaa"], + ["nhs_mhs_party_key", "aaa-111111"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ] + ], + [ + ["nhs_id_code", "aaa"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ] + ] + ], + "questionnaire_responses": { + "spine_mhs/1": [ + { + "id": "277d020e-0389-4113-b44f-f659d2b0ee59", + "questionnaire_name": "spine_mhs", + "questionnaire_version": "1", + "data": { + "Approver URP": "myApprover", + "Contract Property Template Key": "14", + "Date Approved": "20010101010101", + "Date DNS Approved": "20010101010101", + "Date Requested": "20010101010101", + "DNS Approver": "myApprover", + "Interaction Type": "fhir", + "Managing Organization": "AAA", + "Reliability Configuration Ack Requested": "never", + "MHS CPA ID": "00000000000a", + "Reliability Configuration Duplication Elimination": "never", + "Address": "https://test.C3O9X.nhs.uk/", + "MHS FQDN": "test.C3O9X.nhs.uk", + "MHS IP Address": "0.0.0.0", + "MHS Is Authenticated": "none", + "MHS Manufacturer Organisation": "LSP04", + "MHS Party key": "AAA-111111", + "Product Key": "111", + "Product Name": "My AAA Product", + "Product Version": "2005.02", + "Requestor URP": "myRequestor", + "Unique Identifier": "00000000000a" + }, + "created_on": "2024-11-20T10:54:18.995983+00:00" + } + ] + }, + "device_reference_data": { "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": ["*"] } + } + }, + { + "Device": { + "id": "44d37e03-1bba-4300-970e-f083604917c0", + "name": "AAA-111111/000000000001 - Accredited System", + "status": "active", + "product_id": "P.VNT-MLW", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "created_on": "2024-11-20T10:54:19.004056+00:00", + "updated_on": "2024-11-20T10:54:19.005653+00:00", + "deleted_on": null, + "keys": [ + { "key_type": "accredited_system_id", "key_value": "000000000001" } + ], + "tags": [ + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"] + ] + ], + "questionnaire_responses": { + "spine_as/1": [ + { + "id": "8e3f6c89-8d86-4827-9168-1866b141d9f3", + "questionnaire_name": "spine_as", + "questionnaire_version": "1", + "data": { + "Approver URP": "myApprover", + "Client ODS Codes": ["AAA"], + "Date Approved": "20010101010101", + "Date Requested": "20010101010101", + "ODS Code": "AAA", + "MHS Manufacturer Organisation": "LSP04", + "Party Key": "AAA-111111", + "Product Key": "111", + "Product Name": "My AAA Product", + "Product Version": "2005.02", + "Requestor URP": "myRequestor", + "Temp UID": "111", + "ASID": "000000000001" + }, + "created_on": "2024-11-20T10:54:18.997768+00:00" + } + ] + }, + "device_reference_data": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": ["*.Interaction ID"], + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": ["*.Interaction ID"] + } + } + }, + { + "Device": { + "id": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e", + "name": "AAA-111111/000000000004 - Accredited System", + "status": "active", + "product_id": "P.VNT-MLW", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "created_on": "2024-11-20T10:54:19.005712+00:00", + "updated_on": "2024-11-20T10:54:19.007286+00:00", + "deleted_on": null, + "keys": [ + { "key_type": "accredited_system_id", "key_value": "000000000004" } + ], + "tags": [ + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk01"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "aaa-111111"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "aaa"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v001" + ], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "aaa"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk04"] + ] + ], + "questionnaire_responses": { + "spine_as/1": [ + { + "id": "b9669830-a25d-41ce-9aa4-0f41a65aaf64", + "questionnaire_name": "spine_as", + "questionnaire_version": "1", + "data": { + "Approver URP": "myApprover", + "Client ODS Codes": ["AAA"], + "Date Approved": "20040404040404", + "Date Requested": "20040404040404", + "ODS Code": "AAA", + "MHS Manufacturer Organisation": "LSP04", + "Party Key": "AAA-111111", + "Product Key": "444", + "Product Name": "My AAA Product", + "Product Version": "2005.02", + "Requestor URP": "myRequestor", + "Temp UID": "444", + "ASID": "000000000004" + }, + "created_on": "2024-11-20T10:54:18.999535+00:00" + } + ] + }, + "device_reference_data": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": ["*.Interaction ID"], + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": ["*.Interaction ID"] + } + } + }, + { + "CpmProduct": { + "id": "P.LU6-Y7D", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "name": "My BBB Product", + "ods_code": "LSP04", + "status": "active", + "created_on": "2024-11-20T10:54:19.017417+00:00", + "updated_on": "2024-11-20T10:54:19.017614+00:00", + "deleted_on": null, + "keys": [{ "key_type": "party_key", "key_value": "BBB-111111" }] + } + }, + { + "DeviceReferenceData": { + "id": "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e", + "name": "BBB-111111 - MHS Message Sets", + "product_id": "P.LU6-Y7D", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "status": "active", + "questionnaire_responses": { + "spine_mhs_message_sets/1": [ + { + "id": "719577ca-919e-486d-b0d1-e5e06388051c", + "questionnaire_name": "spine_mhs_message_sets", + "questionnaire_version": "1", + "data": { + "MHS IN": "READ_PRACTITIONER_ROLE_R4_V002", + "MHS SN": "urn:nhs:names:services:ers", + "Interaction ID": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002" + }, + "created_on": "2024-11-20T10:54:19.015021+00:00" + }, + { + "id": "417fe8ec-2fc1-4a38-80fc-7cb0ab5245e9", + "questionnaire_name": "spine_mhs_message_sets", + "questionnaire_version": "1", + "data": { + "MHS IN": "READ_PRACTITIONER_ROLE_R4_V002", + "MHS SN": "urn:nhs:names:services:ers", + "Interaction ID": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003" + }, + "created_on": "2024-11-20T10:54:19.015692+00:00" + } + ] + }, + "created_on": "2024-11-20T10:54:19.017673+00:00", + "updated_on": "2024-11-20T10:54:19.017837+00:00", + "deleted_on": null + } + }, + { + "DeviceReferenceData": { + "id": "b4186163-23ec-41fa-abc2-5fe8b0fe9cab", + "name": "BBB-111111 - AS Additional Interactions", + "product_id": "P.LU6-Y7D", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "status": "active", + "questionnaire_responses": { + "spine_as_additional_interactions/1": [ + { + "id": "4fc814dd-6309-4c8f-92ac-ef450292c058", + "questionnaire_name": "spine_as_additional_interactions", + "questionnaire_version": "1", + "data": { + "Interaction ID": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002" + }, + "created_on": "2024-11-20T10:54:19.016015+00:00" + }, + { + "id": "048c60e7-f664-4b02-b1ad-78460c47ba17", + "questionnaire_name": "spine_as_additional_interactions", + "questionnaire_version": "1", + "data": { + "Interaction ID": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003" + }, + "created_on": "2024-11-20T10:54:19.016328+00:00" + }, + { + "id": "f43844e2-0514-4140-a110-b3cb400e6d9d", + "questionnaire_name": "spine_as_additional_interactions", + "questionnaire_version": "1", + "data": { + "Interaction ID": "urn:nhs:names:services:pds:QUPA_IN040000UK02" + }, + "created_on": "2024-11-20T10:54:19.016638+00:00" + }, + { + "id": "4a379a26-65b0-4d2d-9fef-9a92b92df293", + "questionnaire_name": "spine_as_additional_interactions", + "questionnaire_version": "1", + "data": { + "Interaction ID": "urn:nhs:names:services:pds:QUPA_IN040000UK03" + }, + "created_on": "2024-11-20T10:54:19.016947+00:00" + } + ] + }, + "created_on": "2024-11-20T10:54:19.019795+00:00", + "updated_on": "2024-11-20T10:54:19.020066+00:00", + "deleted_on": null + } + }, + { + "Device": { + "id": "a5c17f6a-560d-4553-af40-9095ab84e807", + "name": "BBB-111111 - Message Handling System", + "status": "active", + "product_id": "P.LU6-Y7D", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "created_on": "2024-11-20T10:54:19.017931+00:00", + "updated_on": "2024-11-20T10:54:19.019737+00:00", + "deleted_on": null, + "keys": [ + { "key_type": "cpa_id", "key_value": "00000000000b" }, + { "key_type": "cpa_id", "key_value": "00000000000c" } + ], + "tags": [ + [ + ["nhs_id_code", "bbb"], + ["nhs_mhs_party_key", "bbb-111111"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ] + ], + [ + ["nhs_mhs_party_key", "bbb-111111"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ] + ], + [ + ["nhs_mhs_party_key", "bbb-111111"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ] + ], + [ + ["nhs_id_code", "bbb"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ] + ], + [ + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ] + ], + [ + ["nhs_id_code", "bbb"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ] + ], + [ + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ] + ], + [ + ["nhs_id_code", "bbb"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_id_code", "bbb"], + ["nhs_mhs_party_key", "bbb-111111"], + [ + "nhs_mhs_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ] + ], + [["nhs_mhs_party_key", "bbb-111111"]], + [["nhs_id_code", "bbb"]] + ], + "questionnaire_responses": { + "spine_mhs/1": [ + { + "id": "2dfdf37f-53e6-43be-9a96-9430e24604ac", + "questionnaire_name": "spine_mhs", + "questionnaire_version": "1", + "data": { + "Approver URP": "myApprover", + "Contract Property Template Key": "14", + "Date Approved": "20020202020202", + "Date DNS Approved": "20020202020202", + "Date Requested": "20020202020202", + "DNS Approver": "myApprover", + "Interaction Type": "fhir", + "Managing Organization": "BBB", + "Reliability Configuration Ack Requested": "never", + "MHS CPA ID": "00000000000b", + "Reliability Configuration Duplication Elimination": "never", + "Address": "https://test.C3O9X.nhs.uk/", + "MHS FQDN": "test.C3O9X.nhs.uk", + "MHS IP Address": "0.0.0.0", + "MHS Is Authenticated": "none", + "MHS Manufacturer Organisation": "LSP04", + "MHS Party key": "BBB-111111", + "Product Key": "111", + "Product Name": "My BBB Product", + "Product Version": "2005.02", + "Requestor URP": "myRequestor", + "Unique Identifier": "00000000000b" + }, + "created_on": "2024-11-20T10:54:19.010898+00:00" + } + ] + }, + "device_reference_data": { "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": ["*"] } + } + }, + { + "Device": { + "id": "6924122e-86da-45b3-9c2e-b6a3609b1ed9", + "name": "BBB-111111/000000000002 - Accredited System", + "status": "active", + "product_id": "P.LU6-Y7D", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "created_on": "2024-11-20T10:54:19.020121+00:00", + "updated_on": "2024-11-20T10:54:19.021912+00:00", + "deleted_on": null, + "keys": [ + { "key_type": "accredited_system_id", "key_value": "000000000002" } + ], + "tags": [ + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ], + ["nhs_mhs_manufacturer_org", "lsp04"] + ] + ], + "questionnaire_responses": { + "spine_as/1": [ + { + "id": "c793754b-1eb9-49d3-99dc-a57e5d2589b1", + "questionnaire_name": "spine_as", + "questionnaire_version": "1", + "data": { + "Approver URP": "myApprover", + "Client ODS Codes": ["BBB"], + "Date Approved": "20020202020202", + "Date Requested": "20020202020202", + "ODS Code": "BBB", + "MHS Manufacturer Organisation": "LSP04", + "Party Key": "BBB-111111", + "Product Key": "222", + "Product Name": "My BBB Product", + "Product Version": "2005.02", + "Requestor URP": "myRequestor", + "Temp UID": "222", + "ASID": "000000000002" + }, + "created_on": "2024-11-20T10:54:19.012568+00:00" + } + ] + }, + "device_reference_data": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": ["*.Interaction ID"], + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": ["*.Interaction ID"] + } + } + }, + { + "Device": { + "id": "22129a26-6179-421b-9822-e375408b0d08", + "name": "BBB-111111/000000000003 - Accredited System", + "status": "active", + "product_id": "P.LU6-Y7D", + "product_team_id": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441", + "ods_code": "LSP04", + "created_on": "2024-11-20T10:54:19.021975+00:00", + "updated_on": "2024-11-20T10:54:19.023792+00:00", + "deleted_on": null, + "keys": [ + { "key_type": "accredited_system_id", "key_value": "000000000003" } + ], + "tags": [ + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"], + ["nhs_mhs_manufacturer_org", "lsp04"] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk02"], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ], + ["nhs_mhs_manufacturer_org", "lsp04"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v003" + ] + ], + [ + ["nhs_as_client", "bbb"], + ["nhs_as_svc_ia", "urn:nhs:names:services:pds:qupa_in040000uk03"], + ["nhs_mhs_party_key", "bbb-111111"] + ], + [ + ["nhs_as_client", "bbb"], + [ + "nhs_as_svc_ia", + "urn:nhs:names:services:ers:read_practitioner_role_r4_v002" + ], + ["nhs_mhs_manufacturer_org", "lsp04"] + ] + ], + "questionnaire_responses": { + "spine_as/1": [ + { + "id": "1aa1c3db-a8e2-4509-b69f-9627baa4dcf7", + "questionnaire_name": "spine_as", + "questionnaire_version": "1", + "data": { + "Approver URP": "myApprover", + "Client ODS Codes": ["BBB"], + "Date Approved": "20030303030303", + "Date Requested": "20030303030303", + "ODS Code": "BBB", + "MHS Manufacturer Organisation": "LSP04", + "Party Key": "BBB-111111", + "Product Key": "333", + "Product Name": "My BBB Product", + "Product Version": "2005.02", + "Requestor URP": "myRequestor", + "Temp UID": "333", + "ASID": "000000000003" + }, + "created_on": "2024-11-20T10:54:19.014329+00:00" + } + ] + }, + "device_reference_data": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": ["*.Interaction ID"], + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": ["*.Interaction ID"] + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.0.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.0.json new file mode 100644 index 000000000..5b67e1438 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.0.json @@ -0,0 +1,475 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "sk": { "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "pk_read": { "S": "PT#" }, + "sk_read": { "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "root": { "BOOL": true }, + "id": { "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "name": { "S": "LSP04 (EPR)" }, + "ods_code": { "S": "LSP04" }, + "status": { "S": "active" }, + "created_on": { "S": "2024-11-20T10:54:19.001479+00:00" }, + "updated_on": { "NULL": true }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "epr_id" }, + "key_value": { "S": "EPR-LSP04" } + } + } + ] + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "PT#EPR-LSP04" }, + "sk": { "S": "PT#EPR-LSP04" }, + "pk_read": { "S": "PT#" }, + "sk_read": { "S": "PT#EPR-LSP04" }, + "root": { "BOOL": false }, + "id": { "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "name": { "S": "LSP04 (EPR)" }, + "ods_code": { "S": "LSP04" }, + "status": { "S": "active" }, + "created_on": { "S": "2024-11-20T10:54:19.001479+00:00" }, + "updated_on": { "NULL": true }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "epr_id" }, + "key_value": { "S": "EPR-LSP04" } + } + } + ] + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "P#P.VNT-MLW" }, + "sk": { "S": "P#P.VNT-MLW" }, + "pk_read": { "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "sk_read": { "S": "P#P.VNT-MLW" }, + "root": { "BOOL": true }, + "id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "name": { "S": "My AAA Product" }, + "ods_code": { "S": "LSP04" }, + "status": { "S": "active" }, + "created_on": { "S": "2024-11-20T10:54:19.001733+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.002057+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "party_key" }, + "key_value": { "S": "AAA-111111" } + } + } + ] + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "P#AAA-111111" }, + "sk": { "S": "P#AAA-111111" }, + "pk_read": { "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "sk_read": { "S": "P#AAA-111111" }, + "root": { "BOOL": false }, + "id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "name": { "S": "My AAA Product" }, + "ods_code": { "S": "LSP04" }, + "status": { "S": "active" }, + "created_on": { "S": "2024-11-20T10:54:19.001733+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.002057+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "party_key" }, + "key_value": { "S": "AAA-111111" } + } + } + ] + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DRD#3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6" }, + "sk": { "S": "DRD#3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "DRD#3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6" }, + "root": { "BOOL": true }, + "id": { "S": "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6" }, + "name": { "S": "AAA-111111 - MHS Message Sets" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "questionnaire_responses": { + "M": { + "spine_mhs_message_sets/1": { + "L": [ + { + "M": { + "id": { "S": "5e4cab5e-bcbd-47f6-afa2-7a2b86853ca5" }, + "questionnaire_name": { "S": "spine_mhs_message_sets" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "MHS IN": { "S": "READ_PRACTITIONER_ROLE_R4_V001" }, + "MHS SN": { "S": "urn:nhs:names:services:ers" }, + "Interaction ID": { + "S": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.000224+00:00" } + } + } + ] + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.002130+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.002249+00:00" }, + "deleted_on": { "NULL": true } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DRD#d3d0e6b8-8277-4849-8e8d-5cb035af5536" }, + "sk": { "S": "DRD#d3d0e6b8-8277-4849-8e8d-5cb035af5536" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "DRD#d3d0e6b8-8277-4849-8e8d-5cb035af5536" }, + "root": { "BOOL": true }, + "id": { "S": "d3d0e6b8-8277-4849-8e8d-5cb035af5536" }, + "name": { "S": "AAA-111111 - AS Additional Interactions" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "questionnaire_responses": { + "M": { + "spine_as_additional_interactions/1": { + "L": [ + { + "M": { + "id": { "S": "170711a5-2e77-453b-a04f-4723cf8e9f87" }, + "questionnaire_name": { + "S": "spine_as_additional_interactions" + }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Interaction ID": { + "S": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V001" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.000557+00:00" } + } + }, + { + "M": { + "id": { "S": "cb431ce5-5de2-42cd-9430-2e0b0ad91639" }, + "questionnaire_name": { + "S": "spine_as_additional_interactions" + }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Interaction ID": { + "S": "urn:nhs:names:services:pds:QUPA_IN040000UK01" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.000872+00:00" } + } + }, + { + "M": { + "id": { "S": "36fa5061-f9b7-4980-8cf7-abafdb25f670" }, + "questionnaire_name": { + "S": "spine_as_additional_interactions" + }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Interaction ID": { + "S": "urn:nhs:names:services:pds:QUPA_IN040000UK04" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.001186+00:00" } + } + } + ] + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.003795+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.004000+00:00" }, + "deleted_on": { "NULL": true } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": true }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "M": { + "spine_mhs/1": { + "L": [ + { + "M": { + "id": { "S": "277d020e-0389-4113-b44f-f659d2b0ee59" }, + "questionnaire_name": { "S": "spine_mhs" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Approver URP": { "S": "myApprover" }, + "Contract Property Template Key": { "S": "14" }, + "Date Approved": { "S": "20010101010101" }, + "Date DNS Approved": { "S": "20010101010101" }, + "Date Requested": { "S": "20010101010101" }, + "DNS Approver": { "S": "myApprover" }, + "Interaction Type": { "S": "fhir" }, + "Managing Organization": { "S": "AAA" }, + "Reliability Configuration Ack Requested": { + "S": "never" + }, + "MHS CPA ID": { "S": "00000000000a" }, + "Reliability Configuration Duplication Elimination": { + "S": "never" + }, + "Address": { "S": "https://test.C3O9X.nhs.uk/" }, + "MHS FQDN": { "S": "test.C3O9X.nhs.uk" }, + "MHS IP Address": { "S": "0.0.0.0" }, + "MHS Is Authenticated": { "S": "none" }, + "MHS Manufacturer Organisation": { "S": "LSP04" }, + "MHS Party key": { "S": "AAA-111111" }, + "Product Key": { "S": "111" }, + "Product Name": { "S": "My AAA Product" }, + "Product Version": { "S": "2005.02" }, + "Requestor URP": { "S": "myRequestor" }, + "Unique Identifier": { "S": "00000000000a" } + } + }, + "created_on": { "S": "2024-11-20T10:54:18.995983+00:00" } + } + } + ] + } + } + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#00000000000a" }, + "sk": { "S": "D#00000000000a" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "D#00000000000a" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DT#nhs_mhs_party_key=aaa-111111" }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { "S": "DT#nhs_mhs_party_key=aaa-111111" }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { + "S": "DT#nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.1.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.1.json new file mode 100644 index 000000000..7fb2febf9 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.1.json @@ -0,0 +1,515 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { "S": "DT#nhs_id_code=aaa" }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { "S": "DT#nhs_id_code=aaa" }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DT#nhs_id_code=aaa&nhs_mhs_party_key=aaa-111111" }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { "S": "DT#nhs_id_code=aaa&nhs_mhs_party_key=aaa-111111" }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_mhs_party_key=aaa-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { + "S": "DT#nhs_mhs_party_key=aaa-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_id_code=aaa&nhs_mhs_party_key=aaa-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { + "S": "DT#nhs_id_code=aaa&nhs_mhs_party_key=aaa-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_id_code=aaa&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "pk_read": { + "S": "DT#nhs_id_code=aaa&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk_read": { "S": "D#192133bc-7077-4163-9387-9856969dd412" }, + "root": { "BOOL": false }, + "id": { "S": "192133bc-7077-4163-9387-9856969dd412" }, + "name": { "S": "AAA-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.002315+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.003736+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000a" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/2WTS46rVhCGIyWLiWQpYJqHPbgDOLzhYDAcXlIGgDHGvB/2AY+ygB5k0NlDhllEVpAVxem+ytVV17j0/V+pqn776Y9/fvzhvX59+/nVU+lJ46GfukoGCGoummTUeV5ZEGW0ie1oTIPQsslAhuQSobo+q/HAxE4+Tp50lLci1Eu3GQqV19hRrmmSf9bb6++fsMfR+Ib1MBN8xYZynLVLQ/dOvu6N0ga3opP9PGqYYfL9JanlOL4aTuX3KJUD1PSFG24BauTVDWIjbplTIssb1DIwCSnHDam4iMSitnzJ5uFlbItL8aFkflJyR/Gb0hEz1FOJypsFnNuePR7YQD540ppV/dAJGIjGxPI6/g/25cvba/0Jl4/SO+7h8oOWcSYLafsKa/taEXroG+KLVUY3A/k6oDWp2Ml0YUrdbBi3wwOtt3av8kIcIgsHgpEMXc5b+ESC2fqw/+tTnD9a/8dJGX6Pu+QaWAzTLcfrtIVjTxyx7kYNexkAjo+oAtqmMcxyunn0Azq9HSf1MawDR1LGO/SyrWKM9OyW07RUGjhsB6scDBEtesoWhqgwugkr+Njdny0bQ9y1VsppuslBzAtdZDyV1XsLSUX5UP77O+VHALHTAegskuCRPbBZWaaQbBLxWdccKrKEueacYH+L1L2S7kIO3sRLFYVdzIwed1+SdeRuL4k+02vGgzPf1Kk2mO6iZh63I0X30l684UDNIWn3DNGQ9/i8zkjsuNRErPZggUnVMtkMOZ4rxWkvvKQ4/obOtK7SDrWgKXkXBrl4sjFIJIzpmH7f9Nvrn9+NsYbaxxhYQpJ8L2bi4vopju572WkKVTTLXlfu9rkCNnXebMsdhOJhzwVq+PJY7UNHUJ23Zn2tzMJeJB/CIyJSj7XzbKpU+2UDESlWhAafDzJWUy7kno679LSEjXscrmDdFGZ8PXVk6Bxogud32y2Jc+frTea//AvgmA8J3QMAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY/SQBTVBYOyiB9xX0w082CiiaFMC7iUtwY0EoWtwBpfDBnoFCbAtLZTE0w28QfM4/jir/XOQNldv6YvnXvv3HvOued78cfPwg1zLpQ8TmPG6XSzTOu2+qwu1At5xAIlnzmnpwF2MK3hRtutNW27UZs1m2EtfNVyA2eGKW25Sj78ktFUsIhzwhI65WRDlbxz6KnkyfWCrzRJ4aLkTVvJYkAEMSMrXhwnESTR+chXsrzZ5gEln3YjLhIyF8hPopgmYosmdBOviaDoHd0qeWQ3lbzb0/f9K8BfdTC2Lz8lH5iC3nD8v6KqKRpRA/qvFZUrHZLfkN7vc0E1UmCIJtsYpCiGSwaZkwHhZMH4Ap0lC8LZNyKMCgXP85R8PqJrRmZszYAbsA3ZIktMBfLmq6twbnG6Gzt4O0Zd30P9HkDCl4coaf+7Wy+L12y++3+9ZhvG9zjyviUvCBKawt4eL4WI0069LmC01W2cuZ8svkytbFVX8rYe/+ZDbwiy/pEH0XS676NDsxK2zKfkI5NKkZeJJeVCg9G8ijzioNYTnQWpshBEzBKww06uNIf5fuxjvWxd5xNthZV2QBlkrNnmgKPBJkEGdjHmKJhYJY8NjUGrgy2CJ2gfVfJenv+Y+7MEi29Z2IFhe/2jvTmPN9tDBPifcwYX1A80nZBpFa8vJJPleUI1z6lujBzsNAFszcETG3dazY7dtly35bYbLzHuYKwyklq/ALwUba+lAwAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": true }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "M": { + "spine_as/1": { + "L": [ + { + "M": { + "id": { "S": "8e3f6c89-8d86-4827-9168-1866b141d9f3" }, + "questionnaire_name": { "S": "spine_as" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Approver URP": { "S": "myApprover" }, + "Client ODS Codes": { "L": [{ "S": "AAA" }] }, + "Date Approved": { "S": "20010101010101" }, + "Date Requested": { "S": "20010101010101" }, + "ODS Code": { "S": "AAA" }, + "MHS Manufacturer Organisation": { "S": "LSP04" }, + "Party Key": { "S": "AAA-111111" }, + "Product Key": { "S": "111" }, + "Product Name": { "S": "My AAA Product" }, + "Product Version": { "S": "2005.02" }, + "Requestor URP": { "S": "myRequestor" }, + "Temp UID": { "S": "111" }, + "ASID": { "S": "000000000001" } + } + }, + "created_on": { "S": "2024-11-20T10:54:18.997768+00:00" } + } + } + ] + } + } + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#000000000001" }, + "sk": { "S": "D#000000000001" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "D#000000000001" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.2.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.2.json new file mode 100644 index 000000000..b118bbcf8 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.2.json @@ -0,0 +1,550 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04" + }, + "sk": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04" + }, + "sk_read": { "S": "D#44d37e03-1bba-4300-970e-f083604917c0" }, + "root": { "BOOL": false }, + "id": { "S": "44d37e03-1bba-4300-970e-f083604917c0" }, + "name": { "S": "AAA-111111/000000000001 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.004056+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.005653+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000001" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6m6appveQntQtLb0w5uUtdlKwCY1H0IOBX/AHMf/6zYmFsHZ077vzDsP81n6ahYO0toiVMKN68mFCG8YPuMWr6DgOgiXXLZX5pJbGne4qRlc72oWM7nGuGm+MIM51qqNcP4eyzByfc8TbiAXnlhLhHIeiXDx1/+QQag+CIcMoeSISKQba/ZmE/jKJPPJWCGtk1xAOOu/udKLyGgwJX3fkaGihKJt2yigPhCRJFmvgm7olLL9U0LaMJEpxb8d5Tw3C4Xm8HZKhsKLV2IZxYFiGgWvwnNDEaXkRw/TMTUQTsYiiBJyLxMFrCY1lhZCdRz4TryMfqxiqtVy7TE9UGOYEDVCMhXhNPef8gMdK9BOi+oI9Qzfz65TXSe/iuKfyfWGzO8G+aqSPd19anRfDGOoLAOpbuEsduFEp7qhgDWdzhjtdYwe4y3L6nZNfk1pj1KMRdj6BtD8LWUoAgAA" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": true }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "M": { + "spine_as/1": { + "L": [ + { + "M": { + "id": { "S": "b9669830-a25d-41ce-9aa4-0f41a65aaf64" }, + "questionnaire_name": { "S": "spine_as" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Approver URP": { "S": "myApprover" }, + "Client ODS Codes": { "L": [{ "S": "AAA" }] }, + "Date Approved": { "S": "20040404040404" }, + "Date Requested": { "S": "20040404040404" }, + "ODS Code": { "S": "AAA" }, + "MHS Manufacturer Organisation": { "S": "LSP04" }, + "Party Key": { "S": "AAA-111111" }, + "Product Key": { "S": "444" }, + "Product Name": { "S": "My AAA Product" }, + "Product Version": { "S": "2005.02" }, + "Requestor URP": { "S": "myRequestor" }, + "Temp UID": { "S": "444" }, + "ASID": { "S": "000000000004" } + } + }, + "created_on": { "S": "2024-11-20T10:54:18.999535+00:00" } + } + } + ] + } + } + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.3.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.3.json new file mode 100644 index 000000000..4d0acc662 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.3.json @@ -0,0 +1,520 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { "S": "D#000000000004" }, + "sk": { "S": "D#000000000004" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.VNT-MLW" + }, + "sk_read": { "S": "D#000000000004" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk01&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=aaa-111111" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.4.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.4.json new file mode 100644 index 000000000..96f420307 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.4.json @@ -0,0 +1,582 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v001&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04" + }, + "sk": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "pk_read": { + "S": "DT#nhs_as_client=aaa&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk04" + }, + "sk_read": { "S": "D#4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "root": { "BOOL": false }, + "id": { "S": "4ec9c8a8-37ff-4085-bf3f-e93e9e3ac23e" }, + "name": { "S": "AAA-111111/000000000004 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.VNT-MLW" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.005712+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.007286+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000004" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/8VVubLjVBQkIOBTqHIVkmxtDgiu9t1aLUtVBLJ2a5esNeIDJnz8AZ9AQEBAwEcQEJLyD/i9eUPVzBBMNHPjU6e6+/bp/vHrn/755quX98PTt29+EdBBBOr5avEhDe3vaRX1JwD4xdks0InhQcFVVO9ZVL8Vtbq5k882eriXcrQ1HV+q82G00U01Wt3uSvNSugbD95Nqhwgv9+jdyodhKURZTdso7wbFSNXH+EYyLACZPMyIKrKemDabSMUyvciytU63AVGbVj8vgD4Y2uxSctA1MeCViUgtCzze05vf34MNI5ph9LRBAfvI2TNK70iX62d0wrisYrVRy8aVXHFYGvT9SUcvSESolmGwRRaPRHQ/l9vd5eo9GRCsVaNirtZy2RYahCKVjfL3i4RalxAJMUroOElm+jnI7QEcquZ8pPNSZR1xZSyAOTscT+4wkegJ37VFqSQ28Dq3veLJjpr1gMGQcUXd5C2F3/5HeenzKQ+rouOLqfisvMBOmgwvJ8uCO8VpphvZTI+9wYwthsNLpWY5kAMycINYyXhG//3Tm6eP4Ps9+znht7hV4SkLLiPbkBX8CusL+/lZ1U/0sx6tTbG++vnn9/28lwyjoVVj4bKL0OuuV4pEvkQYa+BpyHhrK7W7ATOkZJmya7gTKmWBJoI8q6fpiNyEybL19uDJAUn3EVv7KUHqR3SlnRi6Bn57l20yzWNBC0vGk1AVkulDGGBWa+VqL8/piEjXshgAtu7SheCbOH0R96Hu3x/APL2cHVg46uLcRoGp2WhulIt9O8guq7JedJUjRs0RGJu5inegG+YvAcWQEKuLSb0tlx6K8nO3FwjFRqKZdQYRvgmbc2fPQqtjApUWmoZh+HG1k9tgOYtxm9FqiXLVWdA0pJoGHUeStMHF0QH3kMsJseMOr6ba8I8JiTQbVvc72W8PTtp0WX2FrjQQ2AiF5awtMBIvS7KF44IJYpN2Ve/VRH9+ZKJrdwKGlLf7FDjGcboU/pLw0pII0smv2nj1jRgbbHahq3ZlFM4P66XySjuuTTmH5CHlJTf2KqwLz+4SlJzv15LB+pTVc2fPLSnvMV43vARM2vGz0TPE1QBUZdKkLMXBuc3DomwdtzUTATPjx94y2/L0nq6pma1pY+Vw06GEZst4AodAiBp3EKnXs707lLBTildqf31ZaoNnNJ9CbVBtmpEpXpDpTFasvH8+or6FzBlE+yyYU95BJPtoUEquM9hovDPor182VJ/r7JNCNfWDEgc8YUaY7LyNgD8+qDT1JQJMYCOydqh3lCSPGwcVLt94WICz+KVyD7reMQKcJIFv7XiKFS3yjh2ndjhr2x25pyeI40DWsinpHoe8uXNQs52ByU8XcVwILCsFpyMLzfNHSzMU1ISr2WaEk+tVIKweSR80W3lwp52+aitGKw25UyLp4PqEeyyKWltu5s4ISWmb4ea/H/jCvYCobfe2F5SKEE/veiH+7l/EcLT9+AgAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QTUvDQBCGta1Y+6UIHgt78CBI6ibdlKa30B4UrQ398CZlbLYSsElMNkIOBX/AHsf/6zYmFsHZ077zzszD+1n5apcOstqirMWh5/MlxDc6PuMWr2TJc1Fevli9ntXvUg0M09WYvuKaBcA0umY69EyAdY+hPH9PeCy8wPfBi/jShw1HWS1Worz42//gUaw+KA91lBUXBGQXG3YYRoFqksXUUUibtBBQng3fPO4LMhnNyDBweawoZdm2bQTZHIHgJPcq6JZBKds/JWSGKc8o/nVUi735Utke387IGPxkDSuRRIppEr2C78UgMvKjh5mzGzxxIBIpueepAlaTmp4VyroTBW6yEj+tMmPK3Ci0xyyg1jglaoTkKsrTov9UBHSsQM0ONVA2c/wgT6e+SX8VxT/nm5As7kbFqYo9230adF8ME1lbRVxl4S53y4lBDaaANYPOdTow2UDvdyzLMrvmNaUDSjGBuPMNqLp8kygCAAA=" + }, + "device_reference_data": { + "M": { + "3dfd9f0b-0cf3-4c3d-92cd-e379adfaecf6": { + "L": [{ "S": "*.Interaction ID" }] + }, + "d3d0e6b8-8277-4849-8e8d-5cb035af5536": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "P#P.LU6-Y7D" }, + "sk": { "S": "P#P.LU6-Y7D" }, + "pk_read": { "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "sk_read": { "S": "P#P.LU6-Y7D" }, + "root": { "BOOL": true }, + "id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "name": { "S": "My BBB Product" }, + "ods_code": { "S": "LSP04" }, + "status": { "S": "active" }, + "created_on": { "S": "2024-11-20T10:54:19.017417+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.017614+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "party_key" }, + "key_value": { "S": "BBB-111111" } + } + } + ] + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "P#BBB-111111" }, + "sk": { "S": "P#BBB-111111" }, + "pk_read": { "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441" }, + "sk_read": { "S": "P#BBB-111111" }, + "root": { "BOOL": false }, + "id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "name": { "S": "My BBB Product" }, + "ods_code": { "S": "LSP04" }, + "status": { "S": "active" }, + "created_on": { "S": "2024-11-20T10:54:19.017417+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.017614+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "party_key" }, + "key_value": { "S": "BBB-111111" } + } + } + ] + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DRD#b362b7c1-317c-4e1f-86e4-d8cbd0f9524e" }, + "sk": { "S": "DRD#b362b7c1-317c-4e1f-86e4-d8cbd0f9524e" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "DRD#b362b7c1-317c-4e1f-86e4-d8cbd0f9524e" }, + "root": { "BOOL": true }, + "id": { "S": "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e" }, + "name": { "S": "BBB-111111 - MHS Message Sets" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "questionnaire_responses": { + "M": { + "spine_mhs_message_sets/1": { + "L": [ + { + "M": { + "id": { "S": "719577ca-919e-486d-b0d1-e5e06388051c" }, + "questionnaire_name": { "S": "spine_mhs_message_sets" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "MHS IN": { "S": "READ_PRACTITIONER_ROLE_R4_V002" }, + "MHS SN": { "S": "urn:nhs:names:services:ers" }, + "Interaction ID": { + "S": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.015021+00:00" } + } + }, + { + "M": { + "id": { "S": "417fe8ec-2fc1-4a38-80fc-7cb0ab5245e9" }, + "questionnaire_name": { "S": "spine_mhs_message_sets" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "MHS IN": { "S": "READ_PRACTITIONER_ROLE_R4_V002" }, + "MHS SN": { "S": "urn:nhs:names:services:ers" }, + "Interaction ID": { + "S": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.015692+00:00" } + } + } + ] + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.017673+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.017837+00:00" }, + "deleted_on": { "NULL": true } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DRD#b4186163-23ec-41fa-abc2-5fe8b0fe9cab" }, + "sk": { "S": "DRD#b4186163-23ec-41fa-abc2-5fe8b0fe9cab" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "DRD#b4186163-23ec-41fa-abc2-5fe8b0fe9cab" }, + "root": { "BOOL": true }, + "id": { "S": "b4186163-23ec-41fa-abc2-5fe8b0fe9cab" }, + "name": { "S": "BBB-111111 - AS Additional Interactions" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "questionnaire_responses": { + "M": { + "spine_as_additional_interactions/1": { + "L": [ + { + "M": { + "id": { "S": "4fc814dd-6309-4c8f-92ac-ef450292c058" }, + "questionnaire_name": { + "S": "spine_as_additional_interactions" + }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Interaction ID": { + "S": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V002" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.016015+00:00" } + } + }, + { + "M": { + "id": { "S": "048c60e7-f664-4b02-b1ad-78460c47ba17" }, + "questionnaire_name": { + "S": "spine_as_additional_interactions" + }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Interaction ID": { + "S": "urn:nhs:names:services:ers:READ_PRACTITIONER_ROLE_R4_V003" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.016328+00:00" } + } + }, + { + "M": { + "id": { "S": "f43844e2-0514-4140-a110-b3cb400e6d9d" }, + "questionnaire_name": { + "S": "spine_as_additional_interactions" + }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Interaction ID": { + "S": "urn:nhs:names:services:pds:QUPA_IN040000UK02" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.016638+00:00" } + } + }, + { + "M": { + "id": { "S": "4a379a26-65b0-4d2d-9fef-9a92b92df293" }, + "questionnaire_name": { + "S": "spine_as_additional_interactions" + }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Interaction ID": { + "S": "urn:nhs:names:services:pds:QUPA_IN040000UK03" + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.016947+00:00" } + } + } + ] + } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.019795+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.020066+00:00" }, + "deleted_on": { "NULL": true } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": true }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "M": { + "spine_mhs/1": { + "L": [ + { + "M": { + "id": { "S": "2dfdf37f-53e6-43be-9a96-9430e24604ac" }, + "questionnaire_name": { "S": "spine_mhs" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Approver URP": { "S": "myApprover" }, + "Contract Property Template Key": { "S": "14" }, + "Date Approved": { "S": "20020202020202" }, + "Date DNS Approved": { "S": "20020202020202" }, + "Date Requested": { "S": "20020202020202" }, + "DNS Approver": { "S": "myApprover" }, + "Interaction Type": { "S": "fhir" }, + "Managing Organization": { "S": "BBB" }, + "Reliability Configuration Ack Requested": { + "S": "never" + }, + "MHS CPA ID": { "S": "00000000000b" }, + "Reliability Configuration Duplication Elimination": { + "S": "never" + }, + "Address": { "S": "https://test.C3O9X.nhs.uk/" }, + "MHS FQDN": { "S": "test.C3O9X.nhs.uk" }, + "MHS IP Address": { "S": "0.0.0.0" }, + "MHS Is Authenticated": { "S": "none" }, + "MHS Manufacturer Organisation": { "S": "LSP04" }, + "MHS Party key": { "S": "BBB-111111" }, + "Product Key": { "S": "111" }, + "Product Name": { "S": "My BBB Product" }, + "Product Version": { "S": "2005.02" }, + "Requestor URP": { "S": "myRequestor" }, + "Unique Identifier": { "S": "00000000000b" } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.010898+00:00" } + } + } + ] + } + } + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#00000000000b" }, + "sk": { "S": "D#00000000000b" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "D#00000000000b" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#00000000000c" }, + "sk": { "S": "D#00000000000c" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "D#00000000000c" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.5.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.5.json new file mode 100644 index 000000000..d3ac2c2c7 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.5.json @@ -0,0 +1,524 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DT#nhs_id_code=bbb&nhs_mhs_party_key=bbb-111111" }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { "S": "DT#nhs_id_code=bbb&nhs_mhs_party_key=bbb-111111" }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { + "S": "DT#nhs_id_code=bbb&nhs_mhs_party_key=bbb-111111&nhs_mhs_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "DT#nhs_mhs_party_key=bbb-111111" }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { "S": "DT#nhs_mhs_party_key=bbb-111111" }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.6.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.6.json new file mode 100644 index 000000000..40ada85a5 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.6.json @@ -0,0 +1,545 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { "S": "DT#nhs_id_code=bbb" }, + "sk": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "pk_read": { "S": "DT#nhs_id_code=bbb" }, + "sk_read": { "S": "D#a5c17f6a-560d-4553-af40-9095ab84e807" }, + "root": { "BOOL": false }, + "id": { "S": "a5c17f6a-560d-4553-af40-9095ab84e807" }, + "name": { "S": "BBB-111111 - Message Handling System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.017931+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.019737+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000b" } + } + }, + { + "M": { + "key_type": { "S": "cpa_id" }, + "key_value": { "S": "00000000000c" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WUy46jRhSGs4jyLJEsxWAuthdZQBkwVdxxcZOywIBpmzvYLmA1DzCLKJq8wzzAPEIeLC13J61Rb2aXyVmXTn31nTr/hx///OOnHx7126efP/61ZwdV0L2jqyRgOfvoYPdAF11J9KgWGGtw8TTncqw0y1Ln0AAV52IjNRNxuBtcQJsaIURnNmO/DYp7dKWLgKZWrLOG5hqlOeeWOg7JJmWkFddmydi3ubdHt47fU9Ryjk/DcvRnGE91kIdmh4UgVbtGna9rX2h41DgM3SvMNAWJeDDI1g6mJ2bn1ELInShgo65lhef69dPHL189Y3XNK683BEEZ8ewKnZQQjddZ6ylTwYg099xfBlrv26VDoItL3ukAiRxcAHVRIe083A7srNutFcWlE5S+LSn9XT8ktIJ69uqeh2EsVGDSnXHu0A6P8MjnaKdwUNMLfd7cn48s0G5TG8e1CrW1TnSxcauu2+dCrJzr6Sl/UP8PsNkXbNDpVG29YX/+CnsKVJc0wLaJhCWZyW8pgaHJDtnm3Bw2sthOFFTMO0fA9mJltMgOHTI4fqH3t5rNTs7y6tRFlCAjAevlDReVNVOL41xpnr7XmJM1tU8hFFjCQlFZpGMjhnhIxWNIcyzrtjZ1bwAfMrEhU+nNIgLnpy1dF68f4/d3hp0ePQyvUB1bB8L5GI+LBCSBHCX1WLGtnU1bdLbALW9kLwsrrhs8b4xLOYouyC68Fh9lH1dt7gY0wJU8uX6EoppLY1le4JrT42Blu8EqysOdXRqeZAli7ljF9uHvW+zZJv9f2fMwC3nmO7FHXuyhnA1q+GqvfIeU9dK/K6Mm68fKXPTSuhRLGHhoxxguviLsQcCqUr6R2VyTmitCN3PG063e7gUxCrBBfBHFXZMJppwVT9B4ue5b8lH+HvMxFOiu5P7Jx8M7a3EP3wZpq1z1OkgsnzEuy9M+6rjIzvrOLaBM73R4fs6CfC8oA1EXOfViR3vX1u13b20dwq2e266yagSnuuUdk/dl0y26uGi7RiRiboqQQPKaK9kvfwP9sqYTnQYAAA==" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/31SXY8SMRTVBYOyLH7EfTHR9MFEE8PQgQF3eGNBI1FYBNb4siGF6UADdMZOxwSTTfwBfawv/lpvy8fu+tV5md5ze++5557v2R8/M7fsudTqMIkZp+PVPCm7+kJf6pfqgAVaPa8EYRBWX4elWpXWS151Qks+8esl36tiWvHq2CNTrR59SWkiWcQ5YYKOOVlRre7ta2p1fDPhKxUJXLS67WqVDYgktmWhGcciAhCdD/pa5VfrXUCrZ62IS0GmEvVFFFMh12hEV/GSSIre07VWB66n1VHb3LevgH+xgnHl6tPqoU1o94b/SyrapAG1pP+aUbhWQfzG9EGHS2qYwoRotI5Bimw4Z4AcdwknM8Zn6EzMCGffiLQqZE5PT7V6MaBLRiZsyWA2mDZks1TYDNScLq7TucPppm333RC1+k3UaQMlfHUmWrn/rtZO4yWbbv7fLNmK8S2PXd1cMwgETWBvT+ZSxkmjXJbQ2mlVz/zPDp8nTrooa3XXtH/7sd0DWf/AQTQDd/poXyyHHftp9dhCCWqmck65NGTMXFkecVDrqUFBqjQEEVMBdtjIlexofhj2sVm2yesTY4WFcUAeZCy59oCjwSZBCnax5sjYWGEX61mDFrtrBE/QNqrV/R3+aefPHCy+5piNH231j7bmPFyt9xGY/5wzuKBOYMYJmVHx5kJSlZ8KauYcm8IIbOQB2VIFj1zcqHkN13ewi0/8k1cYNzDWKUmcXzS0XuOlAwAA" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { "L": [{ "S": "*" }] } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": true }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "M": { + "spine_as/1": { + "L": [ + { + "M": { + "id": { "S": "c793754b-1eb9-49d3-99dc-a57e5d2589b1" }, + "questionnaire_name": { "S": "spine_as" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Approver URP": { "S": "myApprover" }, + "Client ODS Codes": { "L": [{ "S": "BBB" }] }, + "Date Approved": { "S": "20020202020202" }, + "Date Requested": { "S": "20020202020202" }, + "ODS Code": { "S": "BBB" }, + "MHS Manufacturer Organisation": { "S": "LSP04" }, + "Party Key": { "S": "BBB-111111" }, + "Product Key": { "S": "222" }, + "Product Name": { "S": "My BBB Product" }, + "Product Version": { "S": "2005.02" }, + "Requestor URP": { "S": "myRequestor" }, + "Temp UID": { "S": "222" }, + "ASID": { "S": "000000000002" } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.012568+00:00" } + } + } + ] + } + } + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#000000000002" }, + "sk": { "S": "D#000000000002" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "D#000000000002" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.7.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.7.json new file mode 100644 index 000000000..f177edcde --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.7.json @@ -0,0 +1,550 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "root": { "BOOL": false }, + "id": { "S": "6924122e-86da-45b3-9c2e-b6a3609b1ed9" }, + "name": { "S": "BBB-111111/000000000002 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.020121+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.021912+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000002" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0vDQBDH1VasfSmCx8IePAiSutkmtumtj4OitaEPb1K22VUC5uEmEXIo+AH2uH5fpzGxCM6e5j8z//ntfJa/Wgd7WWyUrEah6/MVja519aw26lIeuEzJC6drdbqmsdZ0vrY0w2IdzbKYo1Gzy01GzJ611pU8e094FLuB71NX8JVPPa5kpbBU8vxv/YOLCBIl92G2zGhMs431QRiKAIpoObMByUsLQcnT0ZvL/RhNx3M0ChiPgFKWhsOhorIxpjFHeS9ANwnGZPdAyBpmPKP4t6NS+OamsjW5naMJ9ZMX6sSJAKapeKW+G9E4Iz98mNvYUPLYpiJO0T1PARgmNT0LJWu2CFjixD+lEiGwpV5oj9mBmpMUwQjKVSVPivpTcaAjADXbW8JGjh/k16l56a8C/AvuhWh5Ny5WlQfzbVLHuyAqkVVHcLgFW23NEXzdAGCN4IWO+6bR16021ol507vCuI+xSmjU/gaUmqtVKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": true }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "M": { + "spine_as/1": { + "L": [ + { + "M": { + "id": { "S": "1aa1c3db-a8e2-4509-b69f-9627baa4dcf7" }, + "questionnaire_name": { "S": "spine_as" }, + "questionnaire_version": { "S": "1" }, + "data": { + "M": { + "Approver URP": { "S": "myApprover" }, + "Client ODS Codes": { "L": [{ "S": "BBB" }] }, + "Date Approved": { "S": "20030303030303" }, + "Date Requested": { "S": "20030303030303" }, + "ODS Code": { "S": "BBB" }, + "MHS Manufacturer Organisation": { "S": "LSP04" }, + "Party Key": { "S": "BBB-111111" }, + "Product Key": { "S": "333" }, + "Product Name": { "S": "My BBB Product" }, + "Product Version": { "S": "2005.02" }, + "Requestor URP": { "S": "myRequestor" }, + "Temp UID": { "S": "333" }, + "ASID": { "S": "000000000003" } + } + }, + "created_on": { "S": "2024-11-20T10:54:19.014329+00:00" } + } + } + ] + } + } + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.8.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.8.json new file mode 100644 index 000000000..36bb7972b --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.8.json @@ -0,0 +1,520 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { "S": "D#000000000003" }, + "sk": { "S": "D#000000000003" }, + "pk_read": { + "S": "PT#LSP04.ec12b569-ea31-4c28-9559-17d533c78441#P#P.LU6-Y7D" + }, + "sk_read": { "S": "D#000000000003" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.9.json b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.9.json new file mode 100644 index 000000000..56ac85320 --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/stage_data/3.load_fanout_output.9.json @@ -0,0 +1,366 @@ +[ + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk02&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v003" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_party_key=bbb-111111" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Apds%3Aqupa_in040000uk03&nhs_mhs_party_key=bbb-111111" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + }, + { + "PutRequest": { + "Item": { + "pk": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04" + }, + "sk": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "pk_read": { + "S": "DT#nhs_as_client=bbb&nhs_as_svc_ia=urn%3Anhs%3Anames%3Aservices%3Aers%3Aread_practitioner_role_r4_v002&nhs_mhs_manufacturer_org=lsp04" + }, + "sk_read": { "S": "D#22129a26-6179-421b-9822-e375408b0d08" }, + "root": { "BOOL": false }, + "id": { "S": "22129a26-6179-421b-9822-e375408b0d08" }, + "name": { "S": "BBB-111111/000000000003 - Accredited System" }, + "status": { "S": "active" }, + "product_id": { "S": "P.LU6-Y7D" }, + "product_team_id": { + "S": "LSP04.ec12b569-ea31-4c28-9559-17d533c78441" + }, + "ods_code": { "S": "LSP04" }, + "created_on": { "S": "2024-11-20T10:54:19.021975+00:00" }, + "updated_on": { "S": "2024-11-20T10:54:19.023792+00:00" }, + "deleted_on": { "NULL": true }, + "keys": { + "L": [ + { + "M": { + "key_type": { "S": "accredited_system_id" }, + "key_value": { "S": "000000000003" } + } + } + ] + }, + "tags": { + "S": "H4sIAMVbSGcC/9WVu66cVhiFU6RMm3eIhJQZGGCgcAEbhjvDnQEpxQzXgeF+p8oDuDx5gzxCypR5jJR5kMyxz5FlO5IdKbJPdr21WYv/W+v/+dtfvv/umzfnp4cfXv/Bo51AKc7F5AKw2cKqrldAMSiLBAZK0GF0o10SkTeCcuiYQxntl+3U75UtTzIZBEN1xFAFS4vyCS8QmXPii+P76giGOR8I4LXSclFHl1DJikwtbxnsehueFCPCU+vKYhBXJXhiEBXMezXGABawuT5FpgK5xTGA9whERqfVXWohjwpp6XByhCBBodOJDOVTr5cTdT+vXj28fnjPBtInhd+yFMXN9mpSjRDsZFxBtZZFtSwvldUdfbbSAlg0t7Vh+2J57QYLXRW91qzmZpxurs5w7ahYAcxJLdqb166bc0FSkjq8Np2sJ8r9+kow92+kUjchSt2YBZ6wVCZhSetu3+h6CbLwt7I0IaBy7lnW7x/JClvxS8oSWF9IhFWgI54dVWk7H01z28h2NWZENd7fPU/YrNuceFNNe2NTaYpvT77+JP/TzB5c4uUxC62NLc/vmP3zoylcmiOli9caSShbJ8dT7s8xJ84xLx79oo4WX4+wxsxrUNQLIx/8oJwL72ZFpSFdN1KXcKIbeQXWBI47n28H3y9FnfVpsz04nnujvfv1suJEygC2n3aeji46RRcGICQxOjv1Nchvte3WRsxjRnR/95au16RTLMBINMdLIJVk89pmHay09caYqBBJz1PC2bBokTqTcGbTDPqzvQ+npDxPCZbUXQnRIhj2h03ucmcDgbcccircnaY1DL+N47NvQhzNCibRY+RYd466wnCfqzg4AypDebPldm150PALbuBAyno3y/yyL1gBzR00rQmVMK5FTB1Z/BhP87wIyeWYexTfKH4At5uMyIJhuulR7DTofhU2fYRkFufr1ahog7LnHYl9gu3X920g4h37RxsH2kXIFHOIWbkExh2g+MiAcDnulYvNm3IZwShQs6XgomgT1ggGDYSfKqOPh4hUdkmzncOsKCltk21CMGXsIJPK1oVFaBI1Zqj1WmEJbux5a2CM2k4dzrlFennOx2UpKHSOjSW/NlHy/Ld/+4dIH79spD0hqR4jLYFZksxlfOSkqjVnpsBOVyeXls5NFVHCvmAz03wU/hKayP53TYSBcxBiz0309SPs/ZcRBhYyjPy7CP/1AftHXW+BTs0H+mRnA8+UbDhVh8tY71gH3PMVXqTgVhhnnJjAmknxHORon9REDLRCszBchncdgp+XPSZnSDixdifaGb9ax2Uv2lAO5T1E6x7JzSp0KzTVy40q3fukCmTBE2WSWpABgPM6zcFBMQIKI281UozDznNQiBnbruiPGqueVmuQlnyNBRHZLNMhyxVComl0qcjeIqHaNnlmw+hIduLeQvhZNp1L+/+ziSoWB2dPNj/ZZNuv0mRhii7X00tqMvszm4yjrxLmPjXZJ9fddVhf5LpDxssYN0/rLvrxb6iv4QsgDAAA" + }, + "questionnaire_responses": { + "S": "H4sIAMVbSGcC/22QS0/CUBCFFTAiL42JS5K7cGFiircPwLLjsdAoQni4M2RoL6aJtNiHSRck/oBZjv/XS20lJs5d3XNmznyZz8JXPXeQ1JawFGwcVywguFHphbZ0hTnHJrxUAVRLt5cK3ApNMZrcVJYtc6WYLa29BDBsa9UmPH+PRBA6nuuC44uFC2tBWMwiCS/++h/CD+SH8FAlLNgQQrKx0t1sfE+abD4ZS6R1nAmEZ/03R7ghGw2mrO/ZIpCUmO/1egRYHUAoWNoroWsa5/r+SSFpmIiE4t+OYpabhmJ9eDdlQ3CjFVhh5Eumkf8KrhNAmJAfPU7H3CA8GYMfxuxBxBJYTipqUoTlse/ZkRX+WHldl1sqmfaUHKg2jJkcYalKeJr5z9mBjiVos8E1wmqK76XXKa/jX0Xyz8R6w+b3g2xVoTvdfSp8XzpFWLJ8IW9hL3bhTOOaIYEVjc9U3mkaHdVscNXQNfOa8w7nFEHQ+AafOEdzKAIAAA==" + }, + "device_reference_data": { + "M": { + "b362b7c1-317c-4e1f-86e4-d8cbd0f9524e": { + "L": [{ "S": "*.Interaction ID" }] + }, + "b4186163-23ec-41fa-abc2-5fe8b0fe9cab": { + "L": [{ "S": "*.Interaction ID" }] + } + } + } + } + } + } +] diff --git a/src/etl/sds/worker/bulk/tests/test_bulk_e2e.py b/src/etl/sds/worker/bulk/tests/test_bulk_e2e.py new file mode 100644 index 000000000..f6809a61c --- /dev/null +++ b/src/etl/sds/worker/bulk/tests/test_bulk_e2e.py @@ -0,0 +1,204 @@ +from collections import defaultdict +from pathlib import Path + +import boto3 +import pytest +from botocore.config import Config +from domain.core.cpm_product.v1 import CpmProduct +from domain.core.device.v1 import Device +from domain.core.device_reference_data.v1 import DeviceReferenceData +from domain.core.product_team.v1 import ProductTeam +from domain.repository.cpm_product_repository.v1 import CpmProductRepository +from domain.repository.device_reference_data_repository.v1 import ( + DeviceReferenceDataRepository, +) +from domain.repository.device_repository.v1 import DeviceRepository +from domain.repository.product_team_repository.v1 import ProductTeamRepository +from etl_utils.constants import WorkerKey +from etl_utils.trigger.model import StateMachineInput +from event.aws.client import dynamodb_client + +from etl.sds.tests.constants import EtlTestDataPath +from etl.sds.tests.etl_test_utils.ask_s3 import ( + extract_is_empty, + load_is_empty, + transform_is_empty, + was_changelog_number_updated, +) +from etl.sds.tests.etl_test_utils.etl_state import clear_etl_state, get_etl_config +from etl.sds.tests.etl_test_utils.state_machine import execute_state_machine +from test_helpers.pytest_skips import long_running +from test_helpers.terraform import read_terraform_output + +# Configure the boto3 retry settings +config = Config(retries={"max_attempts": 10, "mode": "standard"}) + +PATH_TO_STAGE_DATA = Path(__file__).parent / "stage_data" + + +def _nested_dict(): + return defaultdict(_nested_dict) + + +def _undefault_nested_dict(nested_dict: dict): + return { + k: _undefault_nested_dict(v) if isinstance(v, dict) else v + for k, v in nested_dict.items() + } + + +def aggregate_database(table_name, dynamodb_client): + product_team_repo = ProductTeamRepository( + table_name=table_name, dynamodb_client=dynamodb_client + ) + product_repo = CpmProductRepository( + table_name=table_name, dynamodb_client=dynamodb_client + ) + device_repo = DeviceRepository( + table_name=table_name, dynamodb_client=dynamodb_client + ) + device_ref_data_repo = DeviceReferenceDataRepository( + table_name=table_name, dynamodb_client=dynamodb_client + ) + + nested_dict = lambda: defaultdict(nested_dict) + aggregated_data = nested_dict() + for product_team in product_team_repo.search(): + (product_team_key,) = product_team.keys + _product_team_data = aggregated_data[ProductTeam][product_team_key.key_value] + + for product in product_repo.search(product_team_id=product_team.id): + (product_key,) = product.keys + _product_data = _product_team_data[CpmProduct][product_key.key_value] + + _product_data[Device] = sorted( + device.name + for device in device_repo.search( + product_team_id=product_team.id, product_id=product.id + ) + ) + + _product_data[DeviceReferenceData] = sorted( + device_ref_data.name + for device_ref_data in device_ref_data_repo.search( + product_team_id=product_team.id, product_id=product.id + ) + ) + + return _undefault_nested_dict(aggregated_data) + + +@pytest.mark.integration +def test_bulk_without_trigger_short(): + new_changelog_number = 123 + etl_config = get_etl_config(f"{new_changelog_number}.ldif") + state_machine_input = StateMachineInput.bulk(changelog_number=new_changelog_number) + step_functions_client = boto3.client("stepfunctions", config=config) + s3_client = boto3.client("s3") + db_client = dynamodb_client() # noqa + + # Clean state + clear_etl_state(s3_client=s3_client, etl_config=etl_config) + initial_aggregated_data = aggregate_database( + table_name=etl_config.table_name, dynamodb_client=db_client + ) + assert initial_aggregated_data == {} + + # Initial state + with open(PATH_TO_STAGE_DATA / "0.extract_input.ldif") as f: + input_data = f.read() + s3_client.put_object( + Bucket=etl_config.bucket, Key=WorkerKey.EXTRACT, Body=input_data + ) + + # Execute + execute_state_machine( + state_machine_input=state_machine_input, + step_functions_client=step_functions_client, + ) + + # Final state + assert was_changelog_number_updated( + s3_client=s3_client, + bucket=etl_config.bucket, + new_changelog_number=new_changelog_number, + ) + assert extract_is_empty(s3_client=s3_client, bucket=etl_config.bucket) + assert transform_is_empty(s3_client=s3_client, bucket=etl_config.bucket) + assert load_is_empty(s3_client=s3_client, bucket=etl_config.bucket) + + final_aggregated_data = aggregate_database( + table_name=etl_config.table_name, dynamodb_client=db_client + ) + assert final_aggregated_data == { + ProductTeam: { + "EPR-LSP04": { + CpmProduct: { + "AAA-111111": { + Device: [ + "AAA-111111 - Message Handling System", + "AAA-111111/000000000001 - Accredited System", + "AAA-111111/000000000004 - Accredited System", + ], + DeviceReferenceData: [ + "AAA-111111 - AS Additional Interactions", + "AAA-111111 - MHS Message Sets", + ], + }, + "BBB-111111": { + Device: [ + "BBB-111111 - Message Handling System", + "BBB-111111/000000000002 - Accredited System", + "BBB-111111/000000000003 - Accredited System", + ], + DeviceReferenceData: [ + "BBB-111111 - AS Additional Interactions", + "BBB-111111 - MHS Message Sets", + ], + }, + }, + }, + }, + } + + +@long_running +@pytest.mark.integration +def test_bulk_without_trigger_long(): + new_changelog_number = 123 + etl_config = get_etl_config(f"{new_changelog_number}.ldif") + state_machine_input = StateMachineInput.bulk(changelog_number=new_changelog_number) + step_functions_client = boto3.client("stepfunctions", config=config) + test_data_bucket = read_terraform_output("test_data_bucket.value") + s3_client = boto3.client("s3") + db_client = dynamodb_client() + + # Clean state + clear_etl_state(s3_client=s3_client, etl_config=etl_config) + initial_aggregated_data = aggregate_database( + table_name=etl_config.table_name, dynamodb_client=db_client + ) + assert initial_aggregated_data == {} + + # Initial state + s3_client.copy_object( + Bucket=etl_config.bucket, + Key=WorkerKey.EXTRACT, + CopySource={"Bucket": test_data_bucket, "Key": EtlTestDataPath.FULL_LDIF}, + ) + + # Execute + execute_state_machine( + state_machine_input=state_machine_input, + step_functions_client=step_functions_client, + ) + + # Final state + assert was_changelog_number_updated( + s3_client=s3_client, + bucket=etl_config.bucket, + new_changelog_number=new_changelog_number, + ) + assert extract_is_empty(s3_client=s3_client, bucket=etl_config.bucket) + assert transform_is_empty(s3_client=s3_client, bucket=etl_config.bucket) + assert load_is_empty(s3_client=s3_client, bucket=etl_config.bucket) diff --git a/src/etl/sds/worker/bulk/transform_bulk/__init__.py b/src/etl/sds/worker/bulk/transform_bulk/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/bulk/transform_bulk/make/make.py b/src/etl/sds/worker/bulk/transform_bulk/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/bulk/transform_bulk/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/bulk/transform_bulk/tests/edge_cases/5AW-0000236/transform_bulk_input.json b/src/etl/sds/worker/bulk/transform_bulk/tests/edge_cases/5AW-0000236/transform_bulk_input.json new file mode 100644 index 000000000..513e27576 --- /dev/null +++ b/src/etl/sds/worker/bulk/transform_bulk/tests/edge_cases/5AW-0000236/transform_bulk_input.json @@ -0,0 +1,50 @@ +[ + [ + { + "object_class": "nhsas", + "change_type": "add", + "unique_identifier": "046841411039", + "nhs_approver_urp": "uniqueIdentifier=997539369030,uniqueIdentifier=330760339011,uid=758917667019,ou=People,o=nhs", + "nhs_date_approved": "20080101000000", + "nhs_requestor_urp": "uniqueIdentifier=997539369030,uniqueIdentifier=330760339011,uid=758917667019,ou=People,o=nhs", + "nhs_date_requested": "20061218090000", + "nhs_id_code": "5AW", + "nhs_mhs_manufacturer_org": "X09001", + "nhs_mhs_party_key": "5AW-0000236", + "nhs_product_key": "999", + "nhs_product_name": "Default", + "nhs_product_version": "Default", + "nhs_as_acf": ["RBAC"], + "nhs_as_client": ["RCD"], + "nhs_as_svc_ia": [ + "urn:nhs:names:services:psis:POCD_IN040002UK01", + "urn:nhs:names:services:mm:PORX_IN250101UK04", + "urn:nhs:names:services:psis/POCD_IN050002UK01" + ], + "nhs_temp_uid": null, + "description": null, + "nhs_as_category_bag": null + }, + { + "object_class": "nhsas", + "change_type": "add", + "unique_identifier": "12345", + "nhs_approver_urp": "uniqueIdentifier=997539369030,uniqueIdentifier=330760339011,uid=758917667019,ou=People,o=nhs", + "nhs_date_approved": "20080101000000", + "nhs_requestor_urp": "uniqueIdentifier=997539369030,uniqueIdentifier=330760339011,uid=758917667019,ou=People,o=nhs", + "nhs_date_requested": "20061218090000", + "nhs_id_code": "5AW", + "nhs_mhs_manufacturer_org": "X09001", + "nhs_mhs_party_key": "5AW-0000236", + "nhs_product_key": "999", + "nhs_product_name": "Default", + "nhs_product_version": "Default", + "nhs_as_acf": ["RBAC"], + "nhs_as_client": ["5AW"], + "nhs_as_svc_ia": ["urn:nhs:names:services:mm:PORX_IN250101UK04"], + "nhs_temp_uid": null, + "description": null, + "nhs_as_category_bag": null + } + ] +] diff --git a/src/etl/sds/worker/bulk/transform_bulk/tests/test_transform_bulk_worker.py b/src/etl/sds/worker/bulk/transform_bulk/tests/test_transform_bulk_worker.py new file mode 100644 index 000000000..1b0d59e17 --- /dev/null +++ b/src/etl/sds/worker/bulk/transform_bulk/tests/test_transform_bulk_worker.py @@ -0,0 +1,205 @@ +import os +from collections import deque +from pathlib import Path +from typing import Callable +from unittest import mock + +import pytest +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from event.json import json_load +from moto import mock_aws +from mypy_boto3_s3 import S3Client + +from etl.sds.worker.bulk.tests.test_bulk_e2e import PATH_TO_STAGE_DATA +from test_helpers.dynamodb import mock_table +from test_helpers.uuid import consistent_uuid + +BUCKET_NAME = "my-bucket" +TABLE_NAME = "my-table" +PATH_TO_HERE = Path(__file__).parent + + +@pytest.fixture +def mock_s3_client(): + with mock_aws(), mock_table(TABLE_NAME) as dynamodb_client, mock.patch.dict( + os.environ, + { + "ETL_BUCKET": BUCKET_NAME, + "TABLE_NAME": TABLE_NAME, + "AWS_DEFAULT_REGION": "us-east-1", + }, + clear=True, + ): + from etl.sds.worker.bulk.transform_bulk import transform_bulk + + transform_bulk.EPR_PRODUCT_TEAM_REPOSITORY.client = dynamodb_client + transform_bulk.S3_CLIENT.create_bucket(Bucket=BUCKET_NAME) + yield transform_bulk.S3_CLIENT + + +@pytest.fixture +def put_object(mock_s3_client: S3Client): + return lambda key, body: ( + mock_s3_client.put_object(Bucket=BUCKET_NAME, Key=key, Body=body) + ) + + +@pytest.fixture +def get_object(mock_s3_client: S3Client) -> bytes: + return lambda key: ( + mock_s3_client.get_object(Bucket=BUCKET_NAME, Key=key)["Body"].read() + ) + + +class ConsistentUUID: + def __init__(self): + self.seed = 1 + + def create(self): + uuid = consistent_uuid(self.seed) + self.seed += 1 + return uuid + + +class MockId: + def __init__(self, id): + self.id = id + + +def _assert_domain_object_equal(a, b): + for k in a.keys() - { + "id", + "product_id", + "product_team_id", + "device_reference_data", + "questionnaire_responses", + "created_on", + "updated_on", + "deleted_on", + "tags", + }: + assert a[k] == b[k], f"{k}: {a[k]} not same as {b[k]}" + + +def assert_transform_outputs_equal(created_objects, template_output): + assert len(created_objects) == len(template_output) + assert all(a.keys() == b.keys() for a, b in zip(created_objects, template_output)) + + current_product_id = None + device_reference_data_ids = None + for nested_created_item, nested_template_item in zip( + created_objects, template_output + ): + (object_type_name,) = nested_created_item.keys() + + created_item = nested_created_item[object_type_name] + template_item = nested_template_item[object_type_name] + + if object_type_name == "CpmProduct": + current_product_id = created_item["id"] + device_reference_data_ids = [] + elif object_type_name == "DeviceReferenceData": + device_reference_data_ids.append(created_item["id"]) + + # Verify that the product id is internally consistent + if created_item.get("product_id"): + assert created_item.get("product_id") == current_product_id + + # Verify that the device reference data ids are internally consistent + if created_item.get("device_reference_data"): + assert all( + id in device_reference_data_ids + for id in created_item.get("device_reference_data") + ) + + # Check that this object is broadly consistent with the expectation + assert created_item.keys() == template_item.keys() + _assert_domain_object_equal(created_item, template_item) + + # Check that any questionnaire responses are broadly consistent with the expectation + if "questionnaire_responses" in created_item: + created_questionnaire_response = created_item["questionnaire_responses"] + template_questionnaire_response = template_item["questionnaire_responses"] + assert ( + template_questionnaire_response.keys() + == created_questionnaire_response.keys() + ) + for questionnaire_name in template_questionnaire_response: + for created_response, template_response in zip( + created_questionnaire_response[questionnaire_name], + template_questionnaire_response[questionnaire_name], + ): + _assert_domain_object_equal(created_response, template_response) + return True + + +def test_transform_worker( + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + + from etl.sds.worker.bulk.transform_bulk import transform_bulk + + initial_processed_data = deque([]) + + # Initial state + with open(PATH_TO_STAGE_DATA / "1.extract_output.json") as f: + input_data = deque(json_load(f)) + + put_object(key=WorkerKey.TRANSFORM, body=pkl_dumps_lz4(input_data)) + put_object(key=WorkerKey.LOAD, body=pkl_dumps_lz4(initial_processed_data)) + + # Execute the transform worker + response = transform_bulk.handler(event={}, context=None) + + assert response == { + "stage_name": "transform", + "processed_records": 13, + "unprocessed_records": 0, + "error_message": None, + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.TRANSFORM) + output_data: str = get_object(key=f"{WorkerKey.LOAD}") + n_final_unprocessed = len(pkl_loads_lz4(final_unprocessed_data)) + + assert n_final_unprocessed == 0 + + with open(PATH_TO_STAGE_DATA / "2.transform_output.json") as f: + template_output: list[dict[str, dict]] = json_load(f) + + created_objects: list[dict[str, dict]] = pkl_loads_lz4(output_data) + assert_transform_outputs_equal(created_objects, template_output) + + +@pytest.mark.parametrize("path_to_edge_case", (PATH_TO_HERE / "edge_cases").iterdir()) +def test_transform_worker_edge_cases( + path_to_edge_case: Path, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + + from etl.sds.worker.bulk.transform_bulk import transform_bulk + + initial_processed_data = deque([]) + + # Initial state + with open(path_to_edge_case / "transform_bulk_input.json") as f: + input_data = deque(json_load(f)) + put_object(key=WorkerKey.TRANSFORM, body=pkl_dumps_lz4(input_data)) + put_object(key=WorkerKey.LOAD, body=pkl_dumps_lz4(initial_processed_data)) + + # Execute + response = transform_bulk.handler(event={}, context=None) + assert response["error_message"] is None + + final_unprocessed_data: str = get_object(key=WorkerKey.TRANSFORM) + final_processed_data: str = get_object(key=WorkerKey.LOAD) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + n_final_unprocessed = len(pkl_loads_lz4(final_unprocessed_data)) + + assert n_final_unprocessed == response["unprocessed_records"] + assert n_final_processed == response["processed_records"] diff --git a/src/etl/sds/worker/bulk/transform_bulk/transform_bulk.py b/src/etl/sds/worker/bulk/transform_bulk/transform_bulk.py new file mode 100644 index 000000000..0d463632e --- /dev/null +++ b/src/etl/sds/worker/bulk/transform_bulk/transform_bulk.py @@ -0,0 +1,158 @@ +from collections import deque +from dataclasses import asdict +from types import FunctionType +from typing import TYPE_CHECKING + +import boto3 +from domain.core.aggregate_root import AggregateRoot +from domain.repository.questionnaire_repository.v1.questionnaire_repository import ( + QuestionnaireRepository, +) +from domain.repository.questionnaire_repository.v1.questionnaires import ( + QuestionnaireInstance, +) +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dump_lz4, pkl_dumps_lz4, pkl_load_lz4 +from etl_utils.smart_open import smart_open +from etl_utils.worker.action import apply_action +from etl_utils.worker.exception import truncate_message +from etl_utils.worker.model import WorkerActionResponse, WorkerEvent +from etl_utils.worker.worker_step_chain import execute_step_chain +from event.aws.client import dynamodb_client +from event.environment import BaseEnvironment +from sds.epr.bulk_create.bulk_create import create_complete_epr_product +from sds.epr.bulk_create.bulk_load_fanout import count_indexes +from sds.epr.bulk_create.epr_product_team_repository import EprProductTeamRepository + +from etl.sds.worker.bulk.transform_bulk.utils import smart_open_if_exists + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + + +class TransformWorkerEnvironment(BaseEnvironment): + ETL_BUCKET: str + TABLE_NAME: str + + def s3_path(self, key) -> str: + return f"s3://{self.ETL_BUCKET}/{key}" + + +S3_CLIENT = boto3.client("s3") +ENVIRONMENT = TransformWorkerEnvironment.build() +SERIALISED_EMPTY_DEQUE = pkl_dumps_lz4(deque([])) + + +AS_DEVICE_QUESTIONNAIRE = QuestionnaireRepository().read(QuestionnaireInstance.SPINE_AS) +MHS_DEVICE_QUESTIONNAIRE = QuestionnaireRepository().read( + QuestionnaireInstance.SPINE_MHS +) +MESSAGE_SETS_QUESTIONNAIRE = QuestionnaireRepository().read( + QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS +) +ADDITIONAL_INTERACTIONS_QUESTIONNAIRE = QuestionnaireRepository().read( + QuestionnaireInstance.SPINE_AS_ADDITIONAL_INTERACTIONS +) +ACCREDITED_SYSTEM_FIELD_MAPPING = QuestionnaireRepository().read_field_mapping( + QuestionnaireInstance.SPINE_AS +) +MHS_DEVICE_FIELD_MAPPING = QuestionnaireRepository().read_field_mapping( + QuestionnaireInstance.SPINE_MHS +) +MESSAGE_SETS_FIELD_MAPPING = QuestionnaireRepository().read_field_mapping( + QuestionnaireInstance.SPINE_MHS_MESSAGE_SETS +) +EPR_PRODUCT_TEAM_REPOSITORY = EprProductTeamRepository( + table_name=ENVIRONMENT.TABLE_NAME, dynamodb_client=dynamodb_client() +) + + +def export_domain_objects(objects: list[AggregateRoot]) -> list[dict]: + _obj = [{obj.__class__.__name__: obj.state()} for obj in objects] + return _obj + + +def apply_action( + unprocessed_records: deque, + processed_records: deque, + action: FunctionType, + max_records: int = None, +): + exception = None + index, count_generated_records = 0, 0 + while ( + unprocessed_records + and exception is None + and (max_records is None or count_generated_records < max_records) + ): + record = unprocessed_records[0] + try: + domain_objects = action(record=record) + except Exception as _exception: + msg = truncate_message(str(record)) + _exception.add_note(f"Failed to parse record {index}\n{msg}") + exception = _exception + else: + processed_records += export_domain_objects(domain_objects) + count_generated_records += sum(count_indexes(obj) for obj in domain_objects) + index += 1 + unprocessed_records.popleft() + return exception + + +def transform( + s3_client: "S3Client", + s3_input_path: str, + s3_output_path: str, + max_records: int, +) -> WorkerActionResponse: + with smart_open(s3_path=s3_input_path, s3_client=s3_client) as f: + unprocessed_records: deque[dict] = pkl_load_lz4(f) + + with smart_open_if_exists( + s3_path=s3_output_path, + s3_client=s3_client, + empty_content=SERIALISED_EMPTY_DEQUE, + ) as f: + processed_records = pkl_load_lz4(f) + + product_team_ids = {p.ods_code: p.id for p in EPR_PRODUCT_TEAM_REPOSITORY.search()} + + exception = apply_action( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + action=lambda record: create_complete_epr_product( + party_key_group=record, + mhs_device_questionnaire=MHS_DEVICE_QUESTIONNAIRE, + message_set_questionnaire=MESSAGE_SETS_QUESTIONNAIRE, + additional_interactions_questionnaire=ADDITIONAL_INTERACTIONS_QUESTIONNAIRE, + accredited_system_questionnaire=AS_DEVICE_QUESTIONNAIRE, + mhs_device_field_mapping=MHS_DEVICE_FIELD_MAPPING, + message_set_field_mapping=MESSAGE_SETS_FIELD_MAPPING, + accredited_system_field_mapping=ACCREDITED_SYSTEM_FIELD_MAPPING, + product_team_ids=product_team_ids, + ), + max_records=max_records, + ) + + return WorkerActionResponse( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + exception=exception, + s3_input_path=s3_input_path, + s3_output_path=s3_output_path, + ) + + +def handler(event: dict, context): + _event = WorkerEvent(**event) + response = execute_step_chain( + action=transform, + s3_client=S3_CLIENT, + s3_input_path=ENVIRONMENT.s3_path(WorkerKey.TRANSFORM), + s3_output_path=ENVIRONMENT.s3_path(WorkerKey.LOAD), + unprocessed_dumper=pkl_dump_lz4, + processed_dumper=pkl_dump_lz4, + max_records=_event.max_records, + ) + return asdict(response) diff --git a/src/etl/sds/worker/bulk/transform_bulk/utils.py b/src/etl/sds/worker/bulk/transform_bulk/utils.py new file mode 100644 index 000000000..a1a1c8971 --- /dev/null +++ b/src/etl/sds/worker/bulk/transform_bulk/utils.py @@ -0,0 +1,20 @@ +from contextlib import contextmanager +from typing import TYPE_CHECKING + +from etl_utils.smart_open import smart_open + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + + +@contextmanager +def smart_open_if_exists(s3_client: "S3Client", s3_path: str, empty_content: bytes): + try: + with smart_open(s3_client=s3_client, s3_path=s3_path, mode="rb") as f: + yield f + except: + with smart_open(s3_client=s3_client, s3_path=s3_path, mode="wb") as f: + f.write(empty_content) + + with smart_open(s3_client=s3_client, s3_path=s3_path, mode="rb") as f: + yield f diff --git a/src/etl/sds/worker/update/extract_update/__init__.py b/src/etl/sds/worker/update/extract_update/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/update/extract_update/extract_update.py b/src/etl/sds/worker/update/extract_update/extract_update.py new file mode 100644 index 000000000..f2f7169b6 --- /dev/null +++ b/src/etl/sds/worker/update/extract_update/extract_update.py @@ -0,0 +1,78 @@ +import json +from collections import deque +from dataclasses import asdict +from io import BytesIO +from typing import TYPE_CHECKING + +import boto3 +from etl_utils.constants import WorkerKey +from etl_utils.io import EtlEncoder, pkl_dump_lz4, pkl_load_lz4 +from etl_utils.ldif.ldif import filter_ldif_from_s3_by_property, ldif_dump, parse_ldif +from etl_utils.smart_open import smart_open +from etl_utils.worker.action import apply_action +from etl_utils.worker.model import WorkerActionResponse, WorkerEnvironment, WorkerEvent +from etl_utils.worker.worker_step_chain import execute_step_chain +from event.json import json_loads +from nhs_context_logging import log_action +from sds.domain.constants import FILTER_TERMS +from sds.domain.parse import parse_sds_record + +_log_action_without_inputs = lambda function: log_action(log_args=[], log_result=False)( + function +) + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + + +S3_CLIENT = boto3.client("s3") +ENVIRONMENT = WorkerEnvironment.build() + + +@_log_action_without_inputs +def _read(s3_client: "S3Client", s3_input_path: str) -> deque[dict]: + filtered_ldif = filter_ldif_from_s3_by_property( + s3_path=s3_input_path, filter_terms=FILTER_TERMS, s3_client=s3_client + ) + return deque(parse_ldif(file_opener=BytesIO, path_or_data=filtered_ldif)) + + +def extract( + s3_client: "S3Client", s3_input_path: str, s3_output_path: str, max_records: int +) -> WorkerActionResponse: + unprocessed_records = _read(s3_client=s3_client, s3_input_path=s3_input_path) + + with smart_open(s3_client=s3_client, s3_path=s3_output_path) as f: + processed_records: deque[dict] = pkl_load_lz4(f) + + exception = apply_action( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + action=lambda record: parse_sds_record(*record).dict(), + record_serializer=lambda dn_and_record: json_loads( + json.dumps(dn_and_record[1], cls=EtlEncoder) + ), + max_records=max_records, + ) + + return WorkerActionResponse( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + exception=exception, + s3_input_path=s3_input_path, + s3_output_path=s3_output_path, + ) + + +def handler(event, context): + max_records = WorkerEvent(**event).max_records + response = execute_step_chain( + action=extract, + s3_client=S3_CLIENT, + s3_input_path=ENVIRONMENT.s3_path(WorkerKey.EXTRACT), + s3_output_path=ENVIRONMENT.s3_path(WorkerKey.TRANSFORM), + unprocessed_dumper=ldif_dump, + processed_dumper=pkl_dump_lz4, + max_records=max_records, + ) + return asdict(response) diff --git a/src/etl/sds/worker/update/extract_update/make/make.py b/src/etl/sds/worker/update/extract_update/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/update/extract_update/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/update/extract_update/tests/_test_extract_update_worker.py b/src/etl/sds/worker/update/extract_update/tests/_test_extract_update_worker.py new file mode 100644 index 000000000..428f3417a --- /dev/null +++ b/src/etl/sds/worker/update/extract_update/tests/_test_extract_update_worker.py @@ -0,0 +1,330 @@ +import os +import re +from itertools import permutations +from typing import Callable +from unittest import mock + +import pytest +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from etl_utils.worker.model import WorkerEnvironment +from moto import mock_aws +from mypy_boto3_s3 import S3Client + +LDIF_RECORD_DELIMITER = "\n\n" +BUCKET_NAME = "my-bucket" + +GOOD_SDS_RECORD = """ +dn: uniqueIdentifier=000428682512,ou=Services,o=nhs +objectClass: nhsAS +objectClass: top +nhsApproverURP: uniqueIdentifier=562983788547,uniqueIdentifier=883298590547,uid=503560389549,ou=People,o=nhs +nhsAsClient: RVL +nhsAsSvcIA: urn:nhs:names:services:pds:QUPA_IN040000UK01 +nhsDateApproved: 20090601140104 +nhsDateRequested: 20090601135904 +nhsIDCode: RVL +nhsMhsManufacturerOrg: LSP04 +nhsMHSPartyKey: RVL-806539 +nhsProductKey: 634 +nhsProductName: Cerner Millennium +nhsProductVersion: 2005.02 +nhsRequestorURP: uniqueIdentifier=977624345541,uniqueIdentifier=883298590547,uid=503560389549,ou=People,o=nhs +nhsTempUid: 9713 +uniqueIdentifier: 000428682512 +""" + +ANOTHER_GOOD_SDS_RECORD = """ +dn: uniqueIdentifier=000842065542,ou=Services,o=nhs +objectClass: nhsAS +objectClass: top +description: prtobjfx +nhsApproverURP: uniqueIdentifier=019732391545,uniqueIdentifier=114738800548,uid=803163224543,ou=People,o=nhs +nhsAsACF: AAA +nhsAsClient: 5AW +nhsAsSvcIA: piwhgu:COPC_IN000001UK01 +nhsDateApproved: 20080625141536 +nhsDateRequested: 20080625141515 +nhsIDCode: 5AW +nhsMhsManufacturerOrg: 00000 +nhsMHSPartyKey: 5AW-802977 +nhsProductKey: 2946 +nhsProductName: 04575133 +nhsProductVersion: 23790687 +nhsRequestorURP: uniqueIdentifier=393864514541,uniqueIdentifier=114738800548,uid=803163224543,ou=People,o=nhs +nhsTempUid: 3881 +uniqueIdentifier: 000842065542 +""" + +# Bad because fields are missing (fails domain) +BAD_SDS_RECORD = """ +dn: uniqueIdentifier=000428682512,ou=Services,o=nhs +objectClass: nhsAS +objectClass: top +""" + +# Fatal because DN is missing (fails LDIF parsing) +FATAL_SDS_RECORD = """ +objectClass: nhsAS +objectClass: foo +""" + +PROCESSED_SDS_RECORD = {} # Empty dict as a dummy value, doesn't matter for extract + + +@pytest.fixture +def mock_s3_client(): + with mock_aws(), mock.patch.dict( + os.environ, + {"ETL_BUCKET": BUCKET_NAME, "AWS_DEFAULT_REGION": "us-east-1"}, + clear=True, + ): + from etl.sds.worker.extract_update import extract_update + + extract_update.ENVIRONMENT = WorkerEnvironment.build() + extract_update.S3_CLIENT.create_bucket(Bucket=BUCKET_NAME) + yield extract_update.S3_CLIENT + + +@pytest.fixture +def put_object(mock_s3_client: S3Client): + return lambda key, body: ( + mock_s3_client.put_object(Bucket=BUCKET_NAME, Key=key, Body=body) + ) + + +@pytest.fixture +def get_object(mock_s3_client: S3Client) -> bytes: + return lambda key: ( + mock_s3_client.get_object(Bucket=BUCKET_NAME, Key=key)["Body"].read() + ) + + +def _split_ldif(data: str) -> list[str]: + return list(filter(bool, data.split(LDIF_RECORD_DELIMITER))) + + +@pytest.mark.parametrize( + ("initial_unprocessed_data", "initial_processed_data"), + [ + ("", [PROCESSED_SDS_RECORD] * 10), + ("\n".join([GOOD_SDS_RECORD] * 5), [PROCESSED_SDS_RECORD] * 5), + ("\n".join([GOOD_SDS_RECORD] * 10), []), + ], + ids=["processed-only", "partly-processed", "unprocessed-only"], +) +def test_extract_worker_pass( + initial_unprocessed_data: str, + initial_processed_data: str, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + from etl.sds.worker.extract_update import extract_update + + # Initial state + n_initial_unprocessed = len(_split_ldif(initial_unprocessed_data)) + n_initial_processed = len(initial_processed_data) + put_object(key=WorkerKey.EXTRACT, body=initial_unprocessed_data) + put_object(key=WorkerKey.TRANSFORM, body=pkl_dumps_lz4(initial_processed_data)) + + # Execute the extract worker + response = extract_update.handler(event={}, context=None) + assert response == { + "stage_name": "extract", + "processed_records": 10, + "unprocessed_records": 0, + "error_message": None, + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.EXTRACT).decode() + final_processed_data: str = get_object(key=WorkerKey.TRANSFORM) + n_final_unprocessed = len(_split_ldif(final_unprocessed_data)) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + + # Confirm that everything has now been processed, and that there is no + # unprocessed data left in the bucket + assert n_final_processed == n_initial_unprocessed + n_initial_processed + assert n_final_unprocessed == 0 + + +@pytest.mark.parametrize("max_records", range(1, 10)) +@pytest.mark.parametrize( + ("initial_unprocessed_data", "initial_processed_data"), + [ + ("", [PROCESSED_SDS_RECORD] * 10), + ("\n".join([GOOD_SDS_RECORD] * 5), [PROCESSED_SDS_RECORD] * 5), + ("\n".join([GOOD_SDS_RECORD] * 10), []), + ], + ids=["processed-only", "partly-processed", "unprocessed-only"], +) +def test_extract_worker_pass_max_records( + initial_unprocessed_data: str, + initial_processed_data: str, + max_records: int, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + from etl.sds.worker.extract_update import extract_update + + # Initial state + n_initial_unprocessed = len(_split_ldif(initial_unprocessed_data)) + n_initial_processed = len(initial_processed_data) + put_object(key=WorkerKey.EXTRACT, body=initial_unprocessed_data) + put_object(key=WorkerKey.TRANSFORM, body=pkl_dumps_lz4(initial_processed_data)) + + n_total_processed_records_expected = n_initial_processed + n_unprocessed_records = n_initial_unprocessed + while n_unprocessed_records > 0: + n_newly_processed_records_expected = min(n_unprocessed_records, max_records) + n_unprocessed_records_expected = ( + n_unprocessed_records - n_newly_processed_records_expected + ) + n_total_processed_records_expected += n_newly_processed_records_expected + + # Execute the extract worker + response = extract_update.handler( + event={"max_records": max_records}, context=None + ) + assert response == { + "stage_name": "extract", + "processed_records": n_total_processed_records_expected, + "unprocessed_records": n_unprocessed_records_expected, + "error_message": None, + } + + n_unprocessed_records = response["unprocessed_records"] + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.EXTRACT).decode() + final_processed_data: str = get_object(key=WorkerKey.TRANSFORM) + n_final_unprocessed = len(_split_ldif(final_unprocessed_data)) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + + # Confirm that everything has now been processed, and that there is no + # unprocessed data left in the bucket + assert n_final_processed == n_initial_unprocessed + n_initial_processed + assert n_final_unprocessed == 0 + + +@pytest.mark.parametrize( + "initial_unprocessed_data", + permutations([BAD_SDS_RECORD, GOOD_SDS_RECORD, GOOD_SDS_RECORD]), +) +def test_extract_worker_bad_record( + initial_unprocessed_data: str, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + from etl.sds.worker.extract_update import extract_update + + _initial_unprocessed_data = "\n".join(initial_unprocessed_data) + bad_record_index = initial_unprocessed_data.index(BAD_SDS_RECORD) + + # Initial state + n_initial_processed = 5 + n_initial_unprocessed = len(initial_unprocessed_data) + initial_processed_data = pkl_dumps_lz4(n_initial_processed * [PROCESSED_SDS_RECORD]) + put_object(key=WorkerKey.EXTRACT, body=_initial_unprocessed_data) + put_object(key=WorkerKey.TRANSFORM, body=initial_processed_data) + + # Execute the extract worker + response = extract_update.handler(event={}, context=None) + response["error_message"] = response["error_message"].split("\n")[:24] + + assert response == { + "stage_name": "extract", + "processed_records": n_initial_processed + bad_record_index, + "unprocessed_records": n_initial_unprocessed - bad_record_index, + "error_message": [ + "The following errors were encountered", + " -- Error 1 (ValidationError) --", + f" Failed to parse record {bad_record_index}", + " {'objectclass': ['nhsAS', 'top']}", + " 9 validation errors for NhsAccreditedSystem", + " uniqueidentifier", + " field required (type=value_error.missing)", + " nhsapproverurp", + " field required (type=value_error.missing)", + " nhsdateapproved", + " field required (type=value_error.missing)", + " nhsrequestorurp", + " field required (type=value_error.missing)", + " nhsdaterequested", + " field required (type=value_error.missing)", + " nhsidcode", + " field required (type=value_error.missing)", + " nhsmhspartykey", + " field required (type=value_error.missing)", + " nhsproductkey", + " field required (type=value_error.missing)", + " nhsassvcia", + " field required (type=value_error.missing)", + "Traceback (most recent call last):", + ], + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.EXTRACT).decode() + final_processed_data: str = get_object(key=WorkerKey.TRANSFORM) + n_final_unprocessed = len(_split_ldif(final_unprocessed_data)) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + + # Confirm that there are still unprocessed records, and that there may have been + # some records processed successfully + assert n_final_unprocessed > 0 + assert n_final_processed == n_initial_processed + bad_record_index + assert n_final_unprocessed == n_initial_unprocessed - bad_record_index + + +@pytest.mark.parametrize( + "initial_unprocessed_data", + permutations([FATAL_SDS_RECORD, GOOD_SDS_RECORD, GOOD_SDS_RECORD]), +) +def test_extract_worker_fatal_record( + initial_unprocessed_data: str, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + from etl.sds.worker.extract_update import extract_update + + # Initial state + _initial_unprocessed_data = "\n".join(initial_unprocessed_data) + n_initial_unprocessed = len(initial_unprocessed_data) + n_initial_processed = 5 + initial_processed_data = pkl_dumps_lz4(n_initial_processed * [PROCESSED_SDS_RECORD]) + put_object(key=WorkerKey.EXTRACT, body=_initial_unprocessed_data) + put_object(key=WorkerKey.TRANSFORM, body=initial_processed_data) + + # Execute the extract worker + response = extract_update.handler(event={}, context=None) + + # The line number in the error changes for each example, so + # substitute it for the value 'NUMBER' + subbed_error_message = re.sub( + r"Line \d{1,2}", "Line NUMBER", response["error_message"] + ) + response["error_message"] = subbed_error_message.split("\n")[:4] + + assert response == { + "stage_name": "extract", + "processed_records": None, + "unprocessed_records": None, + "error_message": [ + "The following errors were encountered", + " -- Error 1 (ValueError) --", + " Line NUMBER: First line of record does not start with \"dn:\": 'objectclass'", + "Traceback (most recent call last):", + ], + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.EXTRACT).decode() + final_processed_data: str = get_object(key=WorkerKey.TRANSFORM) + n_final_unprocessed = len(_split_ldif(final_unprocessed_data)) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + + # Confirm that no changes were persisted + assert n_final_unprocessed == n_initial_unprocessed + assert n_final_processed == n_initial_processed diff --git a/src/etl/sds/worker/update/load_update/__init__.py b/src/etl/sds/worker/update/load_update/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/update/load_update/load_update.py b/src/etl/sds/worker/update/load_update/load_update.py new file mode 100644 index 000000000..a7471ed0a --- /dev/null +++ b/src/etl/sds/worker/update/load_update/load_update.py @@ -0,0 +1,63 @@ +from collections import deque +from dataclasses import asdict +from typing import TYPE_CHECKING + +from domain.core.aggregate_root import AggregateRoot +from domain.core.device import DeviceEventDeserializer +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dump_lz4, pkl_load_lz4 +from etl_utils.smart_open import smart_open +from etl_utils.worker.action import apply_action +from etl_utils.worker.model import WorkerActionResponse, WorkerEvent +from etl_utils.worker.worker_step_chain import execute_step_chain +from sds.worker.load import LoadWorkerCache + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + +CACHE = LoadWorkerCache() + + +def load( + s3_client: "S3Client", s3_input_path: str, s3_output_path: str, max_records: int +) -> WorkerActionResponse: + """ + For updates, the transformed data needs converting into constituent events, + which is the expected input for repository.write + """ + + with smart_open(s3_path=s3_input_path, s3_client=s3_client) as f: + unprocessed_records: deque[dict] = pkl_load_lz4(f) + processed_records = deque() + + exception = apply_action( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + action=lambda record: DeviceEventDeserializer.parse(exported_event=record), + max_records=max_records, + ) + + return WorkerActionResponse( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + s3_input_path=s3_input_path, + exception=exception, + ) + + +def handler(event: dict, context): + worker_event = WorkerEvent(**event) + max_records = worker_event.max_records or CACHE.MAX_RECORDS + + response = execute_step_chain( + action=load, + s3_client=CACHE.S3_CLIENT, + s3_input_path=CACHE.ENVIRONMENT.s3_path(WorkerKey.LOAD), + s3_output_path=None, + unprocessed_dumper=pkl_dump_lz4, + processed_dumper=lambda events: CACHE.REPOSITORY.write( + AggregateRoot(events=events) + ), + max_records=max_records, + ) + return asdict(response) diff --git a/src/etl/sds/worker/update/load_update/make/make.py b/src/etl/sds/worker/update/load_update/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/update/load_update/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/update/load_update/tests/_test_load_update_worker.py b/src/etl/sds/worker/update/load_update/tests/_test_load_update_worker.py new file mode 100644 index 000000000..f25daec20 --- /dev/null +++ b/src/etl/sds/worker/update/load_update/tests/_test_load_update_worker.py @@ -0,0 +1,181 @@ +import os +from collections import deque +from typing import Callable +from unittest import mock + +import pytest +from domain.core.device import Device +from etl.sds.worker.load_bulk.tests.test_load_bulk_worker import ( + BUCKET_NAME, + TABLE_NAME, + MockDeviceRepository, + device_factory, +) +from etl.sds.worker.transform_update.utils import export_events +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from moto import mock_aws +from mypy_boto3_s3 import S3Client + +from test_helpers.dynamodb import mock_table + + +@pytest.fixture +def mock_s3_client(): + with mock_aws(), mock.patch.dict( + os.environ, + { + "ETL_BUCKET": BUCKET_NAME, + "TABLE_NAME": TABLE_NAME, + "AWS_DEFAULT_REGION": "us-east-1", + }, + clear=True, + ): + from etl.sds.worker.load_update import load_update + + load_update.CACHE.S3_CLIENT.create_bucket(Bucket=BUCKET_NAME) + yield load_update.CACHE.S3_CLIENT + + +@pytest.fixture +def put_object(mock_s3_client: S3Client): + return lambda key, body: ( + mock_s3_client.put_object(Bucket=BUCKET_NAME, Key=key, Body=body) + ) + + +@pytest.fixture +def get_object(mock_s3_client: S3Client) -> bytes: + return lambda key: ( + mock_s3_client.get_object(Bucket=BUCKET_NAME, Key=key)["Body"].read() + ) + + +@pytest.fixture +def repository(): + with mock_table(TABLE_NAME) as dynamodb_client: + yield MockDeviceRepository( + table_name=TABLE_NAME, dynamodb_client=dynamodb_client + ) + + +@pytest.mark.parametrize( + ("n_initial_unprocessed", "n_initial_processed"), + [(0, 10), (5, 5), (10, 0)], + ids=["processed-only", "partly-processed", "unprocessed-only"], +) +def test_load_worker_pass( + n_initial_unprocessed: int, + n_initial_processed: int, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], + repository: MockDeviceRepository, +): + from etl.sds.worker.load_update import load_update + + # Initial state + initial_unprocessed_data = [ + device_factory(id=i + 1) for i in range(n_initial_unprocessed) + ] + initial_processed_data = [ + device_factory(id=(i + 1) * 1000) for i in range(n_initial_processed) + ] + put_object( + key=WorkerKey.LOAD, + body=pkl_dumps_lz4(deque(export_events(initial_unprocessed_data))), + ) + for _device in initial_processed_data: + repository.write(_device) + + # Execute the load worker + response = load_update.handler(event={}, context=None) + assert response == { + "stage_name": "load", + "processed_records": 2 * n_initial_unprocessed, + "unprocessed_records": 0, + "error_message": None, + } + + # Final state + final_unprocessed_data = pkl_loads_lz4(get_object(key=WorkerKey.LOAD)) + final_processed_data: list[Device] = list(repository.all_devices()) + + initial_ids = sorted( + device.id for device in initial_unprocessed_data + initial_processed_data + ) + final_processed_ids = sorted(device.id for device in final_processed_data) + + # Confirm that everything has now been processed, and that there is no + # unprocessed data left in the bucket + assert final_processed_ids == initial_ids + assert final_unprocessed_data == deque([]) + + +@pytest.mark.parametrize( + ("n_initial_unprocessed", "n_initial_processed"), + [(0, 10), (5, 5), (10, 0)], + ids=["processed-only", "partly-processed", "unprocessed-only"], +) +def test_load_worker_pass_max_records( + n_initial_unprocessed: int, + n_initial_processed: int, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], + repository: MockDeviceRepository, +): + MAX_RECORDS = 7 + + from etl.sds.worker.load_update import load_update + + # Initial state + initial_unprocessed_data = [ + device_factory(id=i + 1) for i in range(n_initial_unprocessed) + ] + initial_processed_data = [ + device_factory(id=(i + 1) * 1000) for i in range(n_initial_processed) + ] + _initial_unprocessed_data = deque(export_events(initial_unprocessed_data)) + put_object( + key=WorkerKey.LOAD, + body=pkl_dumps_lz4(_initial_unprocessed_data), + ) + for _device in initial_processed_data: + repository.write(_device) + + n_unprocessed_records = len(_initial_unprocessed_data) + while n_unprocessed_records > 0: + n_processed_records_expected = min(n_unprocessed_records, MAX_RECORDS) + n_unprocessed_records_expected = ( + n_unprocessed_records - n_processed_records_expected + ) + + # Execute the load worker + response = load_update.handler( + event={ + "max_records": MAX_RECORDS, + }, + context=None, + ) + assert response == { + "stage_name": "load", + "processed_records": n_processed_records_expected, + "unprocessed_records": n_unprocessed_records_expected, + "error_message": None, + } + + n_unprocessed_records = response["unprocessed_records"] + + # Final state + final_unprocessed_data = pkl_loads_lz4(get_object(key=WorkerKey.LOAD)) + final_processed_data: list[Device] = list(repository.all_devices()) + + initial_ids = sorted( + device.id for device in initial_unprocessed_data + initial_processed_data + ) + final_processed_ids = sorted(device.id for device in final_processed_data) + + # Confirm that everything has now been processed, and that there is no + # unprocessed data left in the bucket + assert final_processed_ids == initial_ids + assert final_unprocessed_data == deque([]) diff --git a/src/etl/sds/worker/update/transform_update/__init__.py b/src/etl/sds/worker/update/transform_update/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/etl/sds/worker/update/transform_update/make/make.py b/src/etl/sds/worker/update/transform_update/make/make.py new file mode 100644 index 000000000..f33cd7068 --- /dev/null +++ b/src/etl/sds/worker/update/transform_update/make/make.py @@ -0,0 +1,4 @@ +from builder.lambda_build import build + +if __name__ == "__main__": + build(__file__) diff --git a/src/etl/sds/worker/update/transform_update/tests/_test_transform_update_worker.py b/src/etl/sds/worker/update/transform_update/tests/_test_transform_update_worker.py new file mode 100644 index 000000000..f565465bf --- /dev/null +++ b/src/etl/sds/worker/update/transform_update/tests/_test_transform_update_worker.py @@ -0,0 +1,266 @@ +import os +import re +from collections import deque +from itertools import permutations +from typing import Callable +from unittest import mock +from uuid import uuid4 + +import pytest +from domain.core.device import DeviceType +from domain.core.root import Root +from etl.sds.worker.transform_bulk.tests.test_transform_bulk_worker import ( + BAD_SDS_RECORD_AS_JSON, + BUCKET_NAME, + FATAL_SDS_RECORD_AS_JSON, + GOOD_SDS_RECORD_AS_JSON, + PROCESSED_SDS_JSON_RECORD, + TABLE_NAME, +) +from etl.sds.worker.transform_update.utils import export_events +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dumps_lz4 +from etl_utils.io.test.io_utils import pkl_loads_lz4 +from moto import mock_aws +from mypy_boto3_s3 import S3Client + + +@pytest.fixture +def mock_s3_client(): + with mock_aws(), mock.patch.dict( + os.environ, + { + "ETL_BUCKET": BUCKET_NAME, + "TABLE_NAME": TABLE_NAME, + "AWS_DEFAULT_REGION": "us-east-1", + }, + clear=True, + ): + from etl.sds.worker.transform_update import transform_update + + transform_update.S3_CLIENT.create_bucket(Bucket=BUCKET_NAME) + yield transform_update.S3_CLIENT + + +@pytest.fixture +def put_object(mock_s3_client: S3Client): + return lambda key, body: ( + mock_s3_client.put_object(Bucket=BUCKET_NAME, Key=key, Body=body) + ) + + +@pytest.fixture +def get_object(mock_s3_client: S3Client) -> bytes: + return lambda key: ( + mock_s3_client.get_object(Bucket=BUCKET_NAME, Key=key)["Body"].read() + ) + + +def test_transform_worker_pass_no_dupes( + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + from etl.sds.worker.transform_update import transform_update + + initial_unprocessed_data = deque([GOOD_SDS_RECORD_AS_JSON]) + initial_processed_data = deque([]) + + # Initial state + n_initial_unprocessed = len(initial_unprocessed_data) + n_initial_processed = len(initial_processed_data) + put_object(key=WorkerKey.TRANSFORM, body=pkl_dumps_lz4(initial_unprocessed_data)) + put_object(key=WorkerKey.LOAD, body=pkl_dumps_lz4(initial_processed_data)) + + # Execute the transform worker + response = transform_update.handler(event={}, context=None) + + assert response == { + "stage_name": "transform", + "processed_records": n_initial_processed + 4 * n_initial_unprocessed, + "unprocessed_records": 0, + "error_message": None, + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.TRANSFORM) + final_processed_data: str = get_object(key=WorkerKey.LOAD) + n_final_unprocessed = len(pkl_loads_lz4(final_unprocessed_data)) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + + # Confirm that everything has now been processed, and that there is no + # unprocessed data left in the bucket + assert n_final_processed == n_initial_processed + 4 * n_initial_unprocessed + assert n_final_unprocessed == 0 + + +@pytest.mark.parametrize("max_records", range(1, 10)) +def test_transform_worker_pass_no_dupes_max_records( + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], + max_records: int, +): + from etl.sds.worker.transform_update import transform_update + + initial_unprocessed_data = deque([GOOD_SDS_RECORD_AS_JSON] * 10) + initial_processed_data = deque([]) + + # Initial state + n_initial_unprocessed = len(initial_unprocessed_data) + n_initial_processed = len(initial_processed_data) + put_object(key=WorkerKey.TRANSFORM, body=pkl_dumps_lz4(initial_unprocessed_data)) + put_object(key=WorkerKey.LOAD, body=pkl_dumps_lz4(initial_processed_data)) + + n_total_processed_records_expected = 0 + n_unprocessed_records = n_initial_unprocessed + while n_unprocessed_records > 0: + n_newly_processed_records_expected = min(n_unprocessed_records, max_records) + n_unprocessed_records_expected = ( + n_unprocessed_records - n_newly_processed_records_expected + ) + n_total_processed_records_expected += 4 * n_newly_processed_records_expected + + # Execute the transform worker + response = transform_update.handler( + event={"max_records": max_records}, context=None + ) + assert response == { + "stage_name": "transform", + "processed_records": n_total_processed_records_expected, + "unprocessed_records": n_unprocessed_records_expected, + "error_message": None, + } + + n_unprocessed_records = response["unprocessed_records"] + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.TRANSFORM) + final_processed_data: str = get_object(key=WorkerKey.LOAD) + n_final_unprocessed = len(pkl_loads_lz4(final_unprocessed_data)) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + + # Confirm that everything has now been processed, and that there is no + # unprocessed data left in the bucket + assert n_final_processed == n_initial_processed + 4 * n_initial_unprocessed + assert n_final_unprocessed == 0 + + +@pytest.mark.parametrize( + "initial_unprocessed_data", + permutations( + [BAD_SDS_RECORD_AS_JSON, GOOD_SDS_RECORD_AS_JSON, GOOD_SDS_RECORD_AS_JSON] + ), +) +def test_transform_worker_bad_record( + initial_unprocessed_data: str, + put_object: Callable[[str], None], + get_object: Callable[[str], bytes], +): + from etl.sds.worker.transform_update import transform_update + + _initial_unprocessed_data = pkl_dumps_lz4(deque(initial_unprocessed_data)) + bad_record_index = initial_unprocessed_data.index(BAD_SDS_RECORD_AS_JSON) + + # Initial state + n_initial_processed = 5 + n_initial_unprocessed = len(initial_unprocessed_data) + initial_processed_data = pkl_dumps_lz4( + deque(n_initial_processed * [PROCESSED_SDS_JSON_RECORD]) + ) + put_object(key=WorkerKey.TRANSFORM, body=_initial_unprocessed_data) + put_object(key=WorkerKey.LOAD, body=initial_processed_data) + + # Execute the transform worker + response = transform_update.handler(event={}, context=None) + + response["error_message"] = response["error_message"].split("\n")[:6] + + assert response == { + "stage_name": "transform", + "processed_records": n_initial_processed + 4 * bad_record_index, + "unprocessed_records": n_initial_unprocessed - bad_record_index, + "error_message": [ + "The following errors were encountered", + " -- Error 1 (KeyError) --", + f" Failed to parse record {bad_record_index}", + " {}", + " 'object_class'", + "Traceback (most recent call last):", + ], + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.TRANSFORM) + final_processed_data: str = get_object(key=WorkerKey.LOAD) + n_final_unprocessed = len(pkl_loads_lz4(final_unprocessed_data)) + n_final_processed = len(pkl_loads_lz4(final_processed_data)) + + # Confirm that there are still unprocessed records, and that there may have been + # some records processed successfully + assert n_final_unprocessed > 0 + assert n_final_processed == n_initial_processed + 4 * bad_record_index + assert n_final_unprocessed == n_initial_unprocessed - bad_record_index + + +def test_transform_worker_fatal_record( + put_object: Callable[[str], None], get_object: Callable[[str], str] +): + from etl.sds.worker.transform_update import transform_update + + # Initial state + n_initial_processed = 5 + initial_unprocessed_data = FATAL_SDS_RECORD_AS_JSON + initial_processed_data = pkl_dumps_lz4( + deque(n_initial_processed * [PROCESSED_SDS_JSON_RECORD]) + ) + put_object(key=WorkerKey.TRANSFORM, body=initial_unprocessed_data) + put_object(key=WorkerKey.LOAD, body=initial_processed_data) + + # Execute the transform worker + response = transform_update.handler(event={}, context=None) + + # The line number in the error changes for each example, so + # substitute it for the value 'NUMBER' + response["error_message"] = re.sub( + r"Line \d{1,2}", "Line NUMBER", response["error_message"] + ) + response["error_message"] = response["error_message"].split("\n")[:3] + + assert response == { + "stage_name": "transform", + "processed_records": None, + "unprocessed_records": None, + "error_message": [ + "The following errors were encountered", + " -- Error 1 (RuntimeError) --", + " LZ4F_decompress failed with code: ERROR_frameType_unknown", + ], + } + + # Final state + final_unprocessed_data: str = get_object(key=WorkerKey.TRANSFORM).decode() + final_processed_data: str = get_object(key=WorkerKey.LOAD) + + # Confirm that no changes were persisted + assert final_unprocessed_data == initial_unprocessed_data + assert final_processed_data == initial_processed_data + + +def test__export_events(): + org = Root.create_ods_organisation(ods_code="AAA") + product_team = org.create_product_team(id=uuid4(), name="abc") + + devices = [] + for i in range(3): + device = product_team.create_device( + name=f"device-{i}", device_type=DeviceType.PRODUCT + ) + device.add_tag(foo=str(i)) + devices.append(device) + events = export_events(devices) + for event in events: + assert len(event) == 1 + event_names = [list(event.keys())[0] for event in events] + assert event_names == [ + "device_created_event", + "device_tag_added_event", + ] * len(devices) diff --git a/src/etl/sds/worker/update/transform_update/transform_update.py b/src/etl/sds/worker/update/transform_update/transform_update.py new file mode 100644 index 000000000..7d63a4e03 --- /dev/null +++ b/src/etl/sds/worker/update/transform_update/transform_update.py @@ -0,0 +1,79 @@ +from collections import deque +from dataclasses import asdict +from typing import TYPE_CHECKING + +import boto3 +from domain.core.event import ExportedEventTypeDef +from domain.repository.device_repository import DeviceRepository +from etl.sds.worker.transform_update.utils import export_events +from etl_utils.constants import WorkerKey +from etl_utils.io import pkl_dump_lz4, pkl_load_lz4 +from etl_utils.smart_open import smart_open +from etl_utils.worker.action import apply_action +from etl_utils.worker.model import WorkerActionResponse, WorkerEvent +from etl_utils.worker.worker_step_chain import execute_step_chain +from event.aws.client import dynamodb_client +from event.environment import BaseEnvironment +from sds.cpm_translation import translate + +if TYPE_CHECKING: + from mypy_boto3_s3 import S3Client + + +class TransformWorkerEnvironment(BaseEnvironment): + ETL_BUCKET: str + TABLE_NAME: str + + def s3_path(self, key) -> str: + return f"s3://{self.ETL_BUCKET}/{key}" + + +S3_CLIENT = boto3.client("s3") +ENVIRONMENT = TransformWorkerEnvironment.build() +REPOSITORY = DeviceRepository( + table_name=ENVIRONMENT.TABLE_NAME, dynamodb_client=dynamodb_client() +) + + +def transform( + s3_client: "S3Client", + s3_input_path: str, + s3_output_path: str, + max_records: int, +): + with smart_open(s3_path=s3_input_path, s3_client=s3_client) as f: + unprocessed_records: deque[dict] = pkl_load_lz4(f) + + with smart_open(s3_path=s3_output_path, s3_client=s3_client) as f: + processed_records: deque[ExportedEventTypeDef] = pkl_load_lz4(f) + + exception = apply_action( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + action=lambda record: export_events( + translate(obj=record, repository=REPOSITORY, bulk=False) + ), + max_records=max_records, + ) + + return WorkerActionResponse( + unprocessed_records=unprocessed_records, + processed_records=processed_records, + exception=exception, + s3_input_path=s3_input_path, + s3_output_path=s3_output_path, + ) + + +def handler(event: dict, context): + _event = WorkerEvent(**event) + response = execute_step_chain( + action=transform, + s3_client=S3_CLIENT, + s3_input_path=ENVIRONMENT.s3_path(WorkerKey.TRANSFORM), + s3_output_path=ENVIRONMENT.s3_path(WorkerKey.LOAD), + unprocessed_dumper=pkl_dump_lz4, + processed_dumper=pkl_dump_lz4, + max_records=_event.max_records, + ) + return asdict(response) diff --git a/src/etl/sds/worker/update/transform_update/utils.py b/src/etl/sds/worker/update/transform_update/utils.py new file mode 100644 index 000000000..a17841154 --- /dev/null +++ b/src/etl/sds/worker/update/transform_update/utils.py @@ -0,0 +1,13 @@ +from itertools import chain + +from domain.core.device import Device + + +def export_events(devices: list[Device]) -> list[dict]: + """ + Pulls and chains (flattens) the list of events out of each Device. + The return list of events is enough to reproduce the state of the + provided devices. This is needed for the transform lambda in "updates" + mode. + """ + return list(chain.from_iterable(map(Device.export_events, devices))) diff --git a/src/layers/domain/api/sds/query.py b/src/layers/domain/api/sds/query.py index cece33e11..7af40e4bc 100644 --- a/src/layers/domain/api/sds/query.py +++ b/src/layers/domain/api/sds/query.py @@ -1,49 +1,32 @@ -from functools import cache -from itertools import chain, combinations - from pydantic import BaseModel, Extra, root_validator -class SearchSDSQueryParams(BaseModel): +class SearchSDSDeviceQueryParams(BaseModel, extra=Extra.forbid): + nhs_id_code: str + nhs_as_svc_ia: str + nhs_mhs_manufacturer_org: str = None + nhs_mhs_party_key: str = None + + @root_validator(pre=True) + def client_to_id(cls, values: dict): + nhs_as_client = values.pop("nhs_as_client", None) + nhs_id_code = values.get("nhs_id_code") + if nhs_as_client and not nhs_id_code: + values["nhs_id_code"] = nhs_as_client + return values + def get_non_null_params(self): return self.dict(exclude_none=True) @classmethod - @cache def allowed_field_combinations(cls) -> list[set[str]]: - """ - This method is used to generate all allowed combinations of search fields - for the given query parameters. Down the line this also used to generate - Device.tags in the ETL - """ - mandatory_fields, optional_fields = [], [] - for field_name, field in cls.__fields__.items(): - if field.required: - mandatory_fields.append(field_name) - else: - optional_fields.append(field_name) - - n_minimum_optional_fields = 0 if mandatory_fields else 1 - n_optional_fields = len(optional_fields) - optional_field_combinations = chain.from_iterable( - combinations(optional_fields, n_fields) - for n_fields in range(n_minimum_optional_fields, n_optional_fields + 1) - ) - return [ - {*mandatory_fields, *_optional_field_combination} - for _optional_field_combination in optional_field_combinations + {"nhs_id_code", "nhs_as_svc_ia"}, + {"nhs_id_code", "nhs_as_svc_ia", "nhs_mhs_party_key"}, ] -class SearchSDSDeviceQueryParams(SearchSDSQueryParams, extra=Extra.forbid): - nhs_as_client: str - nhs_as_svc_ia: str - nhs_mhs_manufacturer_org: str = None - nhs_mhs_party_key: str = None - - -class SearchSDSEndpointQueryParams(SearchSDSQueryParams, extra=Extra.forbid): +class SearchSDSEndpointQueryParams(BaseModel, extra=Extra.forbid): nhs_id_code: str = None nhs_mhs_svc_ia: str = None nhs_mhs_party_key: str = None @@ -59,3 +42,6 @@ def check_filters(cls, values: dict): "At least 2 query parameters should be provided of type, nhs_id_code, nhs_mhs_svc_ia and nhs_mhs_party_key" ) return values + + def get_non_null_params(self): + return self.dict(exclude_none=True) diff --git a/src/layers/domain/api/tests/test_search_query.py b/src/layers/domain/api/tests/test_search_query.py index 4be8358b6..7809fb7e2 100644 --- a/src/layers/domain/api/tests/test_search_query.py +++ b/src/layers/domain/api/tests/test_search_query.py @@ -1,10 +1,7 @@ -from typing import Optional - import pytest from domain.api.sds.query import ( SearchSDSDeviceQueryParams, SearchSDSEndpointQueryParams, - SearchSDSQueryParams, ) from pydantic import ValidationError @@ -97,40 +94,3 @@ def test_endpoint_query_accepted(params): def test_endpoint_query_invalid(params): with pytest.raises(ValidationError): search = SearchSDSEndpointQueryParams(**params) - - -def test_allowed_field_combinations(): - class MyModel(SearchSDSQueryParams): - foo: str - bar: Optional[str] - bob: Optional[str] - - assert MyModel.allowed_field_combinations() == [ - {"foo"}, - {"foo", "bar"}, - {"foo", "bob"}, - {"foo", "bar", "bob"}, - ] - - -def test_allowed_field_combinations_all_optional(): - class MyModel(SearchSDSQueryParams): - foo: Optional[str] - bar: Optional[str] - bob: Optional[str] - - assert MyModel.allowed_field_combinations() == [ - { - "foo", - }, - { - "bar", - }, - { - "bob", - }, - {"foo", "bar"}, - {"foo", "bob"}, - {"bar", "bob"}, - {"foo", "bar", "bob"}, - ] diff --git a/src/layers/domain/core/cpm_system_id/generated_ids/product_ids.json b/src/layers/domain/core/cpm_system_id/generated_ids/product_ids.json new file mode 100644 index 000000000..9ab474f02 --- /dev/null +++ b/src/layers/domain/core/cpm_system_id/generated_ids/product_ids.json @@ -0,0 +1,102 @@ +[ + "P.RKK-P46", + "P.MNE-V6V", + "P.HPM-9MC", + "P.PLT-9YV", + "P.46W-MHJ", + "P.7JD-MUC", + "P.3GG-DW6", + "P.AE9-96P", + "P.K6N-D4X", + "P.RVC-APA", + "P.JFX-3M4", + "P.HKM-MGU", + "P.NXD-R7N", + "P.66R-VWJ", + "P.D3Y-H7J", + "P.T46-YEE", + "P.XTW-LG3", + "P.WTJ-FJT", + "P.XWA-VFF", + "P.6YL-D93", + "P.CPY-J4W", + "P.JNH-MWV", + "P.K7C-X7D", + "P.MLH-97C", + "P.PV9-GTU", + "P.JUW-CRP", + "P.HUX-WFD", + "P.9RJ-VTW", + "P.EGF-DHU", + "P.XMX-4CN", + "P.4RE-CKC", + "P.HR9-9PU", + "P.U9F-D3X", + "P.49J-A7U", + "P.JV6-H4R", + "P.THY-GVT", + "P.AY3-ERX", + "P.6DP-3MK", + "P.DUG-WPW", + "P.DKM-L96", + "P.CXW-CRT", + "P.EKF-XRK", + "P.JG7-LCA", + "P.LRN-UWP", + "P.9AK-LMH", + "P.K96-UND", + "P.YUP-T9J", + "P.EJK-ACK", + "P.H9X-PD4", + "P.VKF-LUV", + "P.HWC-GLY", + "P.D3C-YW7", + "P.KM7-439", + "P.RK9-CKM", + "P.CCW-G73", + "P.RYF-MMM", + "P.4CU-UKP", + "P.GV7-FPE", + "P.AEP-C4V", + "P.CTC-UEM", + "P.DYD-3RG", + "P.H6K-7VL", + "P.U6J-EEU", + "P.EWX-ACY", + "P.4HC-WJN", + "P.A4C-EKV", + "P.6AK-96A", + "P.L9N-Y3T", + "P.TVU-MVK", + "P.WW7-FCD", + "P.PPW-73K", + "P.JPT-6AY", + "P.G9T-UAR", + "P.6LF-D3M", + "P.4NT-EGL", + "P.7JR-XAP", + "P.PEH-UFM", + "P.6KC-WPU", + "P.464-URD", + "P.3DR-EK3", + "P.KG3-CHW", + "P.3FL-PTA", + "P.GT4-9DY", + "P.9RW-9FX", + "P.HTJ-YFF", + "P.NMX-MHC", + "P.4KJ-DHT", + "P.3KL-X6F", + "P.DUM-YKT", + "P.F7G-GVH", + "P.4H4-4FJ", + "P.9XP-NX6", + "P.4VH-YLN", + "P.VRA-F9U", + "P.97J-HN9", + "P.3WF-CNA", + "P.TUR-X4P", + "P.DXE-FWE", + "P.C9W-CLJ", + "P.JVG-CA4" +] diff --git a/src/layers/domain/core/cpm_system_id/tests/test_cpm_system_id_v1.py b/src/layers/domain/core/cpm_system_id/tests/test_cpm_system_id_v1.py index 545c6fb00..c2469a259 100644 --- a/src/layers/domain/core/cpm_system_id/tests/test_cpm_system_id_v1.py +++ b/src/layers/domain/core/cpm_system_id/tests/test_cpm_system_id_v1.py @@ -1,5 +1,21 @@ +import os +from pathlib import Path + import pytest from domain.core.cpm_system_id import AsidId, PartyKeyId, ProductId +from event.json import json_load + +PATH_TO_CPM_SYSTEM_IDS = Path(__file__).parent.parent +PRODUCT_IDS_GENERATED_FILE = f"{PATH_TO_CPM_SYSTEM_IDS}/generated_ids/product_ids.json" +generated_product_ids = set() + + +@pytest.fixture(scope="module") +def _get_generated_ids(): + global generated_product_ids + if os.path.exists(PRODUCT_IDS_GENERATED_FILE): + with open(PRODUCT_IDS_GENERATED_FILE, "r") as file: + generated_product_ids = set(json_load(file)) def test_party_key_generator_format_key(): @@ -19,7 +35,7 @@ def test_party_key_generator_validate_key_valid(): [ "ABC000124", # Missing hyphen "ABC-1234", # Number part too short - "ABC-1234567", # Number part too long + "ABC-123456789101112", # Number part too long "ABC-0001A4", # Number part contains a non-digit character "", # Empty string ], @@ -71,9 +87,11 @@ def test_asid_generator_increment_number(): assert generator.id == "223456789013" -def test_product_id_generator_format_key(): +@pytest.mark.repeat(50) +def test_product_id_generator_format_key(_get_generated_ids): generator = ProductId.create() assert generator.id is not None + assert generator.id not in generated_product_ids @pytest.mark.parametrize( diff --git a/src/layers/domain/core/cpm_system_id/v1.py b/src/layers/domain/core/cpm_system_id/v1.py index edadc4551..7c0865a3d 100644 --- a/src/layers/domain/core/cpm_system_id/v1.py +++ b/src/layers/domain/core/cpm_system_id/v1.py @@ -1,13 +1,17 @@ +import os import random import re from abc import ABC, abstractmethod from datetime import datetime +from functools import cache +from pathlib import Path from uuid import uuid4 from domain.core.base import BaseModel from domain.core.device_key import validate_key from domain.core.error import InvalidKeyPattern from domain.core.product_key import ProductKeyType +from event.json import json_load from pydantic import validator FIRST_ASID = 200000099999 @@ -19,11 +23,22 @@ PRODUCT_ID_PATTERN = re.compile( rf"^P\.[{PRODUCT_ID_VALID_CHARS}]{{{PRODUCT_ID_PART_LENGTH}}}-[{PRODUCT_ID_VALID_CHARS}]{{{PRODUCT_ID_PART_LENGTH}}}$" ) + +PATH_TO_CPM_SYSTEM_IDS = Path(__file__).parent +PRODUCT_IDS_GENERATED_FILE = f"{PATH_TO_CPM_SYSTEM_IDS}/generated_ids/product_ids.json" PRODUCT_TEAM_ID_PATTERN = re.compile( r"^[a-zA-Z0-9]+\.([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})$" ) +@cache +def _load_existing_ids(): + if os.path.exists(PRODUCT_IDS_GENERATED_FILE): + with open(PRODUCT_IDS_GENERATED_FILE, "r") as file: + return set(json_load(file)) + return set() + + class CpmSystemId(BaseModel, ABC): __root__: str = None @@ -111,6 +126,8 @@ def create(cls): "".join(rng.choices(PRODUCT_ID_VALID_CHARS, k=PRODUCT_ID_PART_LENGTH)) for _ in range(PRODUCT_ID_NUMBER_OF_PARTS) ) + if f"P.{product_id}" in cls.load_existing_ids(): + return cls.create() return cls(__root__=f"P.{product_id}") @classmethod @@ -118,6 +135,10 @@ def validate_cpm_system_id(cls, cpm_system_id: str) -> bool: """Validate that the ProductId has the correct format.""" return PRODUCT_ID_PATTERN.match(cpm_system_id) is not None + @classmethod + def load_existing_ids(cls): + return _load_existing_ids() + class ProductTeamId(CpmSystemId): @classmethod diff --git a/src/layers/domain/core/device/v1.py b/src/layers/domain/core/device/v1.py index 9036a60d8..d38c5a52c 100644 --- a/src/layers/domain/core/device/v1.py +++ b/src/layers/domain/core/device/v1.py @@ -159,10 +159,6 @@ class DeviceTagsClearedEvent(Event): @dataclass(kw_only=True, slots=True) class QuestionnaireResponseUpdatedEvent(Event): - """ - This is adding the initial questionnaire response from the event body request. - """ - id: str questionnaire_responses: dict[str, list[QuestionnaireResponse]] keys: list[DeviceKey] diff --git a/src/layers/domain/core/validation.py b/src/layers/domain/core/validation.py index cde59125d..8c4deec9b 100644 --- a/src/layers/domain/core/validation.py +++ b/src/layers/domain/core/validation.py @@ -31,7 +31,7 @@ class AccreditedSystem: ID_PATTERN = re.compile(rf"^[a-zA-Z-0-9]+$") class PartyKey: - PARTY_KEY_REGEX = rf"^{_ODS_CODE_REGEX}-[0-9]{{6}}$" + PARTY_KEY_REGEX = rf"^{_ODS_CODE_REGEX}-[0-9]{{6,9}}$" ID_PATTERN = re.compile(PARTY_KEY_REGEX) class CpaId: diff --git a/src/layers/domain/repository/questionnaire_repository/v1/questionnaires/spine_as/field_mapping.json b/src/layers/domain/repository/questionnaire_repository/v1/questionnaires/spine_as/field_mapping.json index 7ae8ed83c..cfe778e9d 100644 --- a/src/layers/domain/repository/questionnaire_repository/v1/questionnaires/spine_as/field_mapping.json +++ b/src/layers/domain/repository/questionnaire_repository/v1/questionnaires/spine_as/field_mapping.json @@ -14,5 +14,5 @@ "nhs_as_acf": "AS ACF", "nhs_temp_uid": "Temp UID", "description": "Description", - "nhs_as_category_bag": "AS Category Bag" + "nhs_as_category_bag": "Category Bag" } diff --git a/src/layers/etl_utils/ldif/_ldif.py b/src/layers/etl_utils/ldif/_ldif.py index 5abde19be..22bc33f7d 100644 --- a/src/layers/etl_utils/ldif/_ldif.py +++ b/src/layers/etl_utils/ldif/_ldif.py @@ -203,7 +203,7 @@ def __next_key_and_value(self): # All values should be valid ascii; we support UTF-8 as a # non-official, backwards compatibility layer. attr_value = unfolded_line[colon_pos + 1 :].encode("utf-8") - return attr_type.lower(), attr_value + return attr_type.lower(), attr_value.strip() def _consume_empty_lines(self): """ diff --git a/src/layers/etl_utils/ldif/ldif.py b/src/layers/etl_utils/ldif/ldif.py index d5b53c204..103b16bc6 100644 --- a/src/layers/etl_utils/ldif/ldif.py +++ b/src/layers/etl_utils/ldif/ldif.py @@ -1,4 +1,5 @@ import re +from base64 import b64decode from collections import defaultdict from io import BytesIO from types import FunctionType @@ -109,11 +110,16 @@ def __init__(self, group_field: str, filter_terms: list[tuple[str, str]]): for key, value in filter_terms ] self.group_filter = re.compile(rf"(?i)^({group_field}): (.*)\n$".encode()).match + self.group_filter_base_64 = re.compile( + rf"(?i)^({group_field}):: (.*)\n$".encode() + ).match self.reset() def flush(self) -> str: if self.group is None: - raise Exception + raise ValueError( + f"No group name assigned to the following group:\n{self.buffer}" + ) self.data[self.group].write(self.buffer) self.reset() @@ -126,6 +132,11 @@ def parse(self, line: bytes): group_match = self.group_filter(line) if group_match: (_, self.group) = group_match.groups() + else: + b64_group_match = self.group_filter_base_64(line) + if b64_group_match: + (_, b64_group) = b64_group_match.groups() + self.group = b64decode(b64_group).strip() if not self.keep and any(filter(line) for filter in self.filters): self.keep = True diff --git a/src/layers/etl_utils/ldif/tests/test_ldif.py b/src/layers/etl_utils/ldif/tests/test_ldif.py index d67bc2db5..f7c902fae 100644 --- a/src/layers/etl_utils/ldif/tests/test_ldif.py +++ b/src/layers/etl_utils/ldif/tests/test_ldif.py @@ -296,6 +296,54 @@ myOtherField: 123 """ +LDIF_TO_FILTER_AND_GROUP_EXAMPLE_BASE_64 = """ +dn: uniqueIdentifier=AAA1 +myField:: QUFB +myOtherField: 123 + +dn: uniqueIdentifier=BBB1 +myfield: BBB +myOtherField: 123 + +dn: uniqueIdentifier=BBB2 +myfield: BBB +myOtherField: 123 + +dn: uniqueIdentifier=AAA2 +myfield: AAA +myOtherField: 123 + +dn: uniqueIdentifier=AAA3 +myField: AAA +myOtherField: 234 + +dn: uniqueIdentifier=BBB3 +myfield:: QkJC +myOtherField: 123 +""" + +FILTERED_AND_GROUPED_LDIF_TO_FILTER_AND_GROUP_EXAMPLE_BASE_64 = """ +dn: uniqueIdentifier=AAA1 +myField:: QUFB +myOtherField: 123 + +dn: uniqueIdentifier=AAA2 +myfield: AAA +myOtherField: 123 + +dn: uniqueIdentifier=BBB1 +myfield: BBB +myOtherField: 123 + +dn: uniqueIdentifier=BBB2 +myfield: BBB +myOtherField: 123 + +dn: uniqueIdentifier=BBB3 +myfield:: QkJC +myOtherField: 123 +""" + @pytest.mark.parametrize( ("raw_distinguished_name", "parsed_distinguished_name"), @@ -390,6 +438,25 @@ def test_filter_and_group_ldif_from_s3_by_property(mocked_open): ) +@mock.patch( + "etl_utils.ldif.ldif._smart_open", + return_value=BytesIO(LDIF_TO_FILTER_AND_GROUP_EXAMPLE_BASE_64.encode()), +) +def test_filter_and_group_ldif_from_s3_by_property_with_b64encoded_group(mocked_open): + with mock_aws(): + s3_client = boto3.client("s3") + filtered_ldif = filter_and_group_ldif_from_s3_by_property( + s3_client=s3_client, + s3_path="s3://dummy_bucket/dummy_key", + group_field="myField", + filter_terms=[("myOtherField", "123")], + ) + assert ( + "".join(data.tobytes().decode() for data in filtered_ldif) + == FILTERED_AND_GROUPED_LDIF_TO_FILTER_AND_GROUP_EXAMPLE_BASE_64 + ) + + @pytest.mark.parametrize( ["raw_ldif", "parsed_ldif"], [ diff --git a/src/layers/etl_utils/worker/action.py b/src/layers/etl_utils/worker/action.py index 389bbe3d1..0158f5100 100644 --- a/src/layers/etl_utils/worker/action.py +++ b/src/layers/etl_utils/worker/action.py @@ -1,6 +1,8 @@ from collections import deque from types import FunctionType +from etl_utils.worker.exception import TRUNCATION_DEPTH, truncate_message + def apply_action( unprocessed_records: deque, @@ -11,11 +13,13 @@ def apply_action( ): index = 0 exception = None + count_generated_records = 0 while ( unprocessed_records and exception is None and (max_records is None or index < max_records) + and (max_records is None or count_generated_records < max_records) ): record = unprocessed_records[0] try: @@ -23,13 +27,20 @@ def apply_action( except Exception as _exception: if record_serializer is not None: record = record_serializer(record) + record = ( + truncate_message(str(record)) + if len(str(record)) > TRUNCATION_DEPTH + else str(record) + ) _exception.add_note(f"Failed to parse record {index}\n{record}") exception = _exception else: if isinstance(response, (list, deque)): processed_records += response + count_generated_records += len(response) else: processed_records.append(response) + count_generated_records += 1 unprocessed_records.popleft() index += 1 return exception diff --git a/src/layers/etl_utils/worker/exception.py b/src/layers/etl_utils/worker/exception.py index ca11d6d73..86ce535d6 100644 --- a/src/layers/etl_utils/worker/exception.py +++ b/src/layers/etl_utils/worker/exception.py @@ -25,6 +25,14 @@ TRUNCATED = "[TRUNCATED]\n" +def truncate_message( + item: str, truncation_depth=TRUNCATION_DEPTH, truncated_note=TRUNCATED +): + if len(item) > truncation_depth: + return item[:truncation_depth] + truncated_note + return item + + def _render_exception(exception: Exception) -> str: """Concatenates an exception with its notes""" _notes = exception.__dict__.get("__notes__", []) @@ -92,9 +100,11 @@ def render_exception( _traceback = "".join(TracebackException.from_exception(exception).format()) if truncation_depth is not None and len(formatted_exception) > truncation_depth: - formatted_exception = formatted_exception[:truncation_depth] + TRUNCATED + formatted_exception = truncate_message( + formatted_exception, truncation_depth=truncation_depth + ) if truncation_depth is not None and len(_traceback) > truncation_depth: - _traceback = _traceback[:truncation_depth] + TRUNCATED + _traceback = truncate_message(_traceback, truncation_depth=truncation_depth) return f"{indentation}{formatted_exception}\n{_traceback}\n" diff --git a/src/layers/sds/cpm_translation/tests/_test_cpm_translation.py b/src/layers/sds/cpm_translation/tests/_test_cpm_translation.py index b4d19f08d..89eb44d04 100644 --- a/src/layers/sds/cpm_translation/tests/_test_cpm_translation.py +++ b/src/layers/sds/cpm_translation/tests/_test_cpm_translation.py @@ -9,6 +9,7 @@ from domain.core.root.v2 import Root from domain.core.validation import ODS_CODE_REGEX, SdsId from domain.repository.device_repository.v2 import DeviceRepository +from etl.sds.worker.transform_update.utils import export_events from etl_utils.ldif.model import DistinguishedName from event.aws.client import dynamodb_client from event.json import json_load @@ -26,7 +27,6 @@ from sds.domain.sds_deletion_request import SdsDeletionRequest from etl.sds.tests.constants import EtlTestDataPath -from etl.sds.worker.transform_update.utils import export_events from test_helpers.dynamodb import mock_table from test_helpers.terraform import read_terraform_output diff --git a/src/layers/sds/domain/nhs_accredited_system.py b/src/layers/sds/domain/nhs_accredited_system.py index b92b2d322..3e63ab19b 100644 --- a/src/layers/sds/domain/nhs_accredited_system.py +++ b/src/layers/sds/domain/nhs_accredited_system.py @@ -27,7 +27,7 @@ class NhsAccreditedSystem(SdsBaseModel): nhs_product_name: Optional[str] = Field(alias="nhsproductname") nhs_product_version: Optional[str] = Field(alias="nhsproductversion") nhs_as_acf: Optional[set[str]] = Field(alias="nhsasacf") - nhs_as_client: Optional[set[str]] = Field(alias="nhsasclient") + nhs_as_client: Optional[set[str]] = Field(alias="nhsasclient", default_factory=set) nhs_as_svc_ia: set[str] = Field(alias="nhsassvcia") nhs_temp_uid: Optional[str] = Field(alias="nhstempuid") description: Optional[str] = Field(alias="description") diff --git a/src/layers/sds/epr/bulk_create/bulk_create.py b/src/layers/sds/epr/bulk_create/bulk_create.py index 53334bc7a..06e17fd45 100644 --- a/src/layers/sds/epr/bulk_create/bulk_create.py +++ b/src/layers/sds/epr/bulk_create/bulk_create.py @@ -31,7 +31,7 @@ def _create_complete_epr_product( mhs_tags: list[dict], additional_interactions_data: list[QuestionnaireResponse], as_device_data: list[QuestionnaireResponse], - as_tags: list[dict], + as_tags: list[list[dict]], product_team_ids: dict[str, str], ) -> list[AggregateRoot]: if ods_code in product_team_ids: @@ -50,14 +50,19 @@ def _create_complete_epr_product( message_sets = create_message_sets( product=product, party_key=party_key, message_set_data=message_set_data ) - mhs_device = create_mhs_device( - product=product, - party_key=party_key, - mhs_device_data=mhs_device_data, - cpa_ids=mhs_cpa_ids, - message_sets_id=message_sets.id, - mhs_tags=mhs_tags, - ) + + mhs_devices = [] + if mhs_device_data: + mhs_device = create_mhs_device( + product=product, + party_key=party_key, + mhs_device_data=mhs_device_data, + cpa_ids=mhs_cpa_ids, + message_sets_id=message_sets.id, + mhs_tags=mhs_tags, + ) + mhs_devices = [mhs_device] + additional_interactions = create_additional_interactions( product=product, party_key=party_key, @@ -71,9 +76,9 @@ def _create_complete_epr_product( as_device_data=data, additional_interactions_id=additional_interactions.id, message_sets_id=message_sets.id, - as_tags=as_tags, + as_tags=tags, ) - for data in as_device_data + for data, tags in zip(as_device_data, as_tags) ] return [ @@ -81,7 +86,7 @@ def _create_complete_epr_product( product, message_sets, additional_interactions, - mhs_device, + *mhs_devices, *as_devices, ] @@ -113,12 +118,25 @@ def create_complete_epr_product( # !! Assumption: All MHSs with this party key have the same basic metadata. # !! Could add a debug test here to ensure all of this metadata is equal # !! between MHSs with this party key. - first_mhs = message_handling_systems[0] - mhs_device_data = get_mhs_device_data( - mhs=first_mhs, - mhs_device_questionnaire=mhs_device_questionnaire, - mhs_device_field_mapping=mhs_device_field_mapping, - ) + ods_code, party_key, product_name = None, None, None + mhs_device_data = None + if message_handling_systems: + first_mhs = message_handling_systems[0] + mhs_device_data = get_mhs_device_data( + mhs=first_mhs, + mhs_device_questionnaire=mhs_device_questionnaire, + mhs_device_field_mapping=mhs_device_field_mapping, + ) + + ods_code = first_mhs["nhs_mhs_manufacturer_org"] + party_key = first_mhs["nhs_mhs_party_key"] + product_name = first_mhs["nhs_product_name"] or first_mhs["nhs_mhs_cpa_id"] + else: + first_as = accredited_systems[0] + ods_code = first_as["nhs_mhs_manufacturer_org"] + party_key = first_as["nhs_mhs_party_key"] + product_name = first_as["nhs_product_name"] + as_device_data = [ get_accredited_system_device_data( accredited_system=accredited_system, @@ -139,15 +157,18 @@ def create_complete_epr_product( ) mhs_tags = get_mhs_tags(message_handling_systems) - as_tags = get_accredited_system_tags(accredited_systems) + as_tags = [ + get_accredited_system_tags(accredited_system) + for accredited_system in accredited_systems + ] return _create_complete_epr_product( - ods_code=first_mhs["nhs_mhs_manufacturer_org"], - party_key=first_mhs["nhs_mhs_party_key"], - product_name=first_mhs["nhs_product_name"], + ods_code=ods_code, + party_key=party_key, + product_name=product_name, mhs_device_data=mhs_device_data, message_set_data=message_set_data, - mhs_cpa_ids=[mhs["nhs_mhs_cpa_id"] for mhs in message_handling_systems], + mhs_cpa_ids=[mhs["unique_identifier"] for mhs in message_handling_systems], mhs_tags=mhs_tags, additional_interactions_data=additional_interactions_data, as_device_data=as_device_data, diff --git a/src/layers/sds/epr/bulk_create/bulk_load_fanout.py b/src/layers/sds/epr/bulk_create/bulk_load_fanout.py new file mode 100644 index 000000000..a3b1ea137 --- /dev/null +++ b/src/layers/sds/epr/bulk_create/bulk_load_fanout.py @@ -0,0 +1,21 @@ +from math import ceil + +from domain.core.cpm_product.v1 import CpmProduct +from domain.core.device.v1 import Device +from domain.core.device_reference_data.v1 import DeviceReferenceData +from domain.core.product_team.v1 import ProductTeam + +FANOUT = 10 + + +def count_indexes(obj: Device | DeviceReferenceData | CpmProduct | ProductTeam): + count = 1 + if isinstance(obj, (Device, CpmProduct, ProductTeam)): + count += len(obj.keys) + if isinstance(obj, (Device)): + count += len(obj.tags) + return count + + +def calculate_batch_size(sequence: list, n_batches: int) -> int: + return ceil(len(sequence) / (n_batches)) or 1 diff --git a/src/layers/sds/epr/bulk_create/bulk_repository.py b/src/layers/sds/epr/bulk_create/bulk_repository.py index 8d9526af3..5c4f79432 100644 --- a/src/layers/sds/epr/bulk_create/bulk_repository.py +++ b/src/layers/sds/epr/bulk_create/bulk_repository.py @@ -1,7 +1,7 @@ import random import time from functools import wraps -from itertools import batched, chain +from itertools import batched from typing import TYPE_CHECKING from botocore.exceptions import ClientError @@ -151,28 +151,23 @@ def __init__(self, table_name, dynamodb_client, batch_size=10): table_name=None, dynamodb_client=None ) - def write(self, items: list[dict]): - def generate_transaction_statements(object_type_name, item): - handler_name = f"handle_{object_type_name}" - handler = getattr(self, handler_name) - batch_write_items = handler(item=item) - - if not isinstance(batch_write_items, list): - batch_write_items = [batch_write_items] - return batch_write_items - - batch_write_items = chain.from_iterable( - ( - generate_transaction_statements(object_type_name, item) - for _item in items - for (object_type_name, item) in _item.items() - ) - ) + def generate_transaction_statements( + self, item_with_name: dict[str, dict] + ) -> list[dict]: + ((object_type_name, item),) = item_with_name.items() + handler_name = f"handle_{object_type_name}" + handler = getattr(self, handler_name) + statements = handler(item=item) + if not isinstance(statements, list): + statements = [statements] + return statements + + def write(self, transaction_statements: list[dict]): responses = [ batch_write_chunk( client=self.client, table_name=self.table_name, chunk=chunk ) - for chunk in batched(batch_write_items, self.batch_size) + for chunk in batched(transaction_statements, self.batch_size) ] return responses diff --git a/src/layers/sds/epr/bulk_create/getters.py b/src/layers/sds/epr/bulk_create/getters.py index 35e596b6b..df4aa47d9 100644 --- a/src/layers/sds/epr/bulk_create/getters.py +++ b/src/layers/sds/epr/bulk_create/getters.py @@ -1,7 +1,4 @@ -from domain.api.sds.query import ( - SearchSDSDeviceQueryParams, - SearchSDSEndpointQueryParams, -) +from domain.api.sds.query import SearchSDSDeviceQueryParams from domain.core.questionnaire import Questionnaire, QuestionnaireResponse from sds.epr.constants import SdsFieldName from sds.epr.tags.tags import is_list_like, sds_metadata_to_device_tags @@ -52,12 +49,7 @@ def get_message_set_data( def get_mhs_tags(message_handling_systems: list[dict]) -> list[dict]: - tags = [] - for mhs in message_handling_systems: - tags += sds_metadata_to_device_tags( - data=mhs, model=SearchSDSEndpointQueryParams - ) - return [dict(tag) for tag in set(tags)] + return [] def get_additional_interactions_data( @@ -91,12 +83,8 @@ def get_accredited_system_device_data( ) -def get_accredited_system_tags( - accredited_systems: list[dict], -) -> list[dict]: - tags = [] - for accredited_system in accredited_systems: - tags += sds_metadata_to_device_tags( - data=accredited_system, model=SearchSDSDeviceQueryParams - ) +def get_accredited_system_tags(accredited_system: dict) -> list[dict]: + tags = sds_metadata_to_device_tags( + data=accredited_system, model=SearchSDSDeviceQueryParams + ) return [dict(tag) for tag in set(tags)] diff --git a/src/layers/sds/epr/bulk_create/tests/conftest.py b/src/layers/sds/epr/bulk_create/tests/conftest.py index 52375da30..a7b689ff9 100644 --- a/src/layers/sds/epr/bulk_create/tests/conftest.py +++ b/src/layers/sds/epr/bulk_create/tests/conftest.py @@ -100,7 +100,7 @@ def accredited_system_2() -> NhsMhs: nhsrequestorurp="requester-456", nhsdaterequested="a week ago", nhsdateapproved="today", - nhsidcode="AAA", + nhsidcode="BBB", nhsmhspartykey="AAA-456789", nhsproductkey="key-123", nhsasclient={"ABC", "JKL", "LMN"}, diff --git a/src/layers/sds/epr/bulk_create/tests/test_bulk_create.py b/src/layers/sds/epr/bulk_create/tests/test_bulk_create.py index 62caeabca..96e9f9d04 100644 --- a/src/layers/sds/epr/bulk_create/tests/test_bulk_create.py +++ b/src/layers/sds/epr/bulk_create/tests/test_bulk_create.py @@ -88,33 +88,7 @@ def mhs_cpa_ids(): @pytest.fixture def mhs_tags(): - return [ - {"nhs_id_code": "BBB", "nhs_mhs_svc_ia": "my-other-interaction-id"}, - {"nhs_mhs_party_key": "BBB-123456"}, - { - "nhs_id_code": "BBB", - "nhs_mhs_party_key": "BBB-123456", - "nhs_mhs_svc_ia": "my-other-interaction-id", - }, - {"nhs_id_code": "AAA", "nhs_mhs_party_key": "AAA-123456"}, - {"nhs_mhs_svc_ia": "my-interaction-id"}, - {"nhs_mhs_svc_ia": "my-other-interaction-id"}, - {"nhs_id_code": "BBB", "nhs_mhs_party_key": "BBB-123456"}, - {"nhs_id_code": "AAA"}, - {"nhs_mhs_party_key": "AAA-123456", "nhs_mhs_svc_ia": "my-interaction-id"}, - {"nhs_id_code": "BBB"}, - {"nhs_mhs_party_key": "AAA-123456"}, - {"nhs_id_code": "AAA", "nhs_mhs_svc_ia": "my-interaction-id"}, - { - "nhs_mhs_party_key": "BBB-123456", - "nhs_mhs_svc_ia": "my-other-interaction-id", - }, - { - "nhs_id_code": "AAA", - "nhs_mhs_party_key": "AAA-123456", - "nhs_mhs_svc_ia": "my-interaction-id", - }, - ] + return [] @pytest.fixture @@ -166,7 +140,7 @@ def as_device_data(): "Date Approved": "today", "Requestor URP": "requester-456", "Date Requested": "a week ago", - "ODS Code": "AAA", + "ODS Code": "BBB", "MHS Manufacturer Organisation": "AAA", "Party Key": "AAA-456789", "Product Key": "key-123", @@ -179,237 +153,46 @@ def as_device_data(): @pytest.fixture def as_tags(): return [ - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-1", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - }, + [ + { + "nhs_id_code": "AAA", + "nhs_as_svc_ia": "interaction-id-1", + }, + { + "nhs_id_code": "AAA", + "nhs_as_svc_ia": "interaction-id-1", + "nhs_mhs_party_key": "AAA-123456", + }, + { + "nhs_id_code": "AAA", + "nhs_as_svc_ia": "interaction-id-2", + }, + { + "nhs_id_code": "AAA", + "nhs_as_svc_ia": "interaction-id-2", + "nhs_mhs_party_key": "AAA-123456", + }, + ], + [ + { + "nhs_id_code": "BBB", + "nhs_as_svc_ia": "interaction-id-2", + }, + { + "nhs_id_code": "BBB", + "nhs_as_svc_ia": "interaction-id-2", + "nhs_mhs_party_key": "AAA-456789", + }, + { + "nhs_id_code": "BBB", + "nhs_as_svc_ia": "interaction-id-4", + }, + { + "nhs_id_code": "BBB", + "nhs_as_svc_ia": "interaction-id-4", + "nhs_mhs_party_key": "AAA-456789", + }, + ], ] @@ -420,6 +203,12 @@ def _fix_up_questionnaire(qr: QuestionnaireResponse, today_string: str) -> dict: return _qr +def _assert_list_of_dict_equal(a: list[dict], b: list[dict]): + _a = sorted(map(sorted, map(dict.items, a))) + _b = sorted(map(sorted, map(dict.items, b))) + assert _a == _b + + @mock.patch( "sds.epr.bulk_create.bulk_create._create_complete_epr_product", side_effect=lambda **kwargs: kwargs, @@ -501,14 +290,12 @@ def test_create_complete_epr_product__intermediate( assert _message_set_data == message_set_data assert _mhs_data == mhs_data - assert all(tag in kwargs["as_tags"] for tag in as_tags) - assert all(tag in as_tags for tag in kwargs["as_tags"]) - assert len(kwargs["as_tags"]) == len(as_tags) - - assert all(tag in kwargs["mhs_tags"] for tag in mhs_tags) - assert all(tag in mhs_tags for tag in kwargs["mhs_tags"]) - assert len(kwargs["mhs_tags"]) == len(mhs_tags) + expected_tags_1, expected_tags_2 = as_tags + tags_1, tags_2 = kwargs["as_tags"] + _assert_list_of_dict_equal(tags_1, expected_tags_1) + _assert_list_of_dict_equal(tags_2, expected_tags_2) + assert kwargs["mhs_tags"] == mhs_tags assert kwargs["mhs_cpa_ids"] == mhs_cpa_ids assert kwargs["ods_code"] == ods_code assert kwargs["party_key"] == party_key diff --git a/src/layers/sds/epr/bulk_create/tests/test_bulk_repository.py b/src/layers/sds/epr/bulk_create/tests/test_bulk_repository.py index 2a5583b80..e850e10bb 100644 --- a/src/layers/sds/epr/bulk_create/tests/test_bulk_repository.py +++ b/src/layers/sds/epr/bulk_create/tests/test_bulk_repository.py @@ -148,7 +148,10 @@ def test_BulkRepository_handle_ProductTeam(dynamodb_client): ) bulk_repo = BulkRepository(table_name=TABLE_NAME, dynamodb_client=dynamodb_client) - bulk_repo.write([{"ProductTeam": product_team.state()}]) + transactions = bulk_repo.generate_transaction_statements( + {"ProductTeam": product_team.state()} + ) + bulk_repo.write(transactions) product_team_by_id = product_team_repo.read(product_team.id) product_team_by_key = product_team_repo.read("EPR-AAA") @@ -166,7 +169,10 @@ def test_BulkRepository_handle_CpmProduct(dynamodb_client): product.clear_events() bulk_repo = BulkRepository(table_name=TABLE_NAME, dynamodb_client=dynamodb_client) - bulk_repo.write([{"CpmProduct": product.state()}]) + transactions = bulk_repo.generate_transaction_statements( + {"CpmProduct": product.state()} + ) + bulk_repo.write(transactions) product_by_id = product_repo.read(product_team.id, product.id) product_by_key = product_repo.read(product_team.id, "AAA-123456") @@ -186,7 +192,8 @@ def test_BulkRepository_handle_Device(dynamodb_client): device.clear_events() bulk_repo = BulkRepository(table_name=TABLE_NAME, dynamodb_client=dynamodb_client) - bulk_repo.write([{"Device": device.state()}]) + transactions = bulk_repo.generate_transaction_statements({"Device": device.state()}) + bulk_repo.write(transactions) device_by_id = device_repo.read(product_team.id, product.id, device.id) device_by_key = device_repo.read(product_team.id, product.id, "123456") @@ -207,7 +214,10 @@ def test_BulkRepository_handle_DeviceReferenceData(dynamodb_client): device_ref_data = product.create_device_reference_data(name="my-product") bulk_repo = BulkRepository(table_name=TABLE_NAME, dynamodb_client=dynamodb_client) - bulk_repo.write([{"DeviceReferenceData": device_ref_data.state()}]) + transactions = bulk_repo.generate_transaction_statements( + {"DeviceReferenceData": device_ref_data.state()} + ) + bulk_repo.write(transactions) device_ref_data_by_id = device_ref_data_repo.read( product_team.id, product.id, device_ref_data.id diff --git a/src/layers/sds/epr/bulk_create/tests/test_epr_product_team_repository.py b/src/layers/sds/epr/bulk_create/tests/test_epr_product_team_repository.py index cc5f585ca..85b96d0be 100644 --- a/src/layers/sds/epr/bulk_create/tests/test_epr_product_team_repository.py +++ b/src/layers/sds/epr/bulk_create/tests/test_epr_product_team_repository.py @@ -40,9 +40,13 @@ def test_get_all_epr_product_teams_local(dynamodb_client): product_teams = [*epr_product_teams, *non_epr_product_teams] shuffle(product_teams) - BulkRepository(table_name="my-table", dynamodb_client=dynamodb_client).write( - [{"ProductTeam": product_team.state()} for product_team in product_teams] - ) + repo = BulkRepository(table_name="my-table", dynamodb_client=dynamodb_client) + transactions = [] + for product_team in product_teams: + transactions += repo.generate_transaction_statements( + {"ProductTeam": product_team.state()} + ) + repo.write(transactions) epr_product_team_repo = EprProductTeamRepository( table_name="my-table", dynamodb_client=dynamodb_client @@ -76,9 +80,14 @@ def test_get_all_epr_product_teams(): product_teams = [*epr_product_teams, *non_epr_product_teams] shuffle(product_teams) - BulkRepository(table_name=table_name, dynamodb_client=client).write( - [{"ProductTeam": product_team.state()} for product_team in product_teams] - ) + repo = BulkRepository(table_name=table_name, dynamodb_client=client) + transactions = [] + for product_team in product_teams: + transactions += repo.generate_transaction_statements( + {"ProductTeam": product_team.state()} + ) + repo.write(transactions) + epr_product_team_repo = EprProductTeamRepository( table_name=table_name, dynamodb_client=client ) diff --git a/src/layers/sds/epr/bulk_create/tests/test_getters.py b/src/layers/sds/epr/bulk_create/tests/test_getters.py index 224dd5210..26cd22632 100644 --- a/src/layers/sds/epr/bulk_create/tests/test_getters.py +++ b/src/layers/sds/epr/bulk_create/tests/test_getters.py @@ -181,309 +181,26 @@ def test_get_additional_interactions_data( def test_get_mhs_tags(mhs_1: NhsMhs, mhs_2: NhsMhs): message_handling_systems = [mhs_1.dict(), mhs_2.dict()] tags = get_mhs_tags(message_handling_systems=message_handling_systems) + assert len(tags) == 0 - expected_tags = [ - { - "nhs_id_code": "AAA", - }, - { - "nhs_mhs_svc_ia": "my-interaction-id", - }, - { - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_id_code": "AAA", - "nhs_mhs_svc_ia": "my-interaction-id", - }, - { - "nhs_id_code": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_mhs_party_key": "AAA-123456", - "nhs_mhs_svc_ia": "my-interaction-id", - }, - { - "nhs_id_code": "AAA", - "nhs_mhs_party_key": "AAA-123456", - "nhs_mhs_svc_ia": "my-interaction-id", - }, - { - "nhs_id_code": "BBB", - }, - { - "nhs_mhs_svc_ia": "my-other-interaction-id", - }, - { - "nhs_mhs_party_key": "BBB-123456", - }, - { - "nhs_id_code": "BBB", - "nhs_mhs_svc_ia": "my-other-interaction-id", - }, - { - "nhs_id_code": "BBB", - "nhs_mhs_party_key": "BBB-123456", - }, - { - "nhs_mhs_party_key": "BBB-123456", - "nhs_mhs_svc_ia": "my-other-interaction-id", - }, - { - "nhs_id_code": "BBB", - "nhs_mhs_party_key": "BBB-123456", - "nhs_mhs_svc_ia": "my-other-interaction-id", - }, - ] - - for tag in tags: - assert tag in expected_tags, f"{tag} not in expected tags" - - for tag in expected_tags: - assert tag in tags, f"Expected {tag} in tags" - - assert len(tags) == len(expected_tags) - -def test_get_accredited_system_tags( - accredited_system_1: NhsAccreditedSystem, accredited_system_2: NhsAccreditedSystem -): - accredited_systems = [accredited_system_1.dict(), accredited_system_2.dict()] - tags = get_accredited_system_tags(accredited_systems=accredited_systems) +def test_get_accredited_system_tags(accredited_system_1: NhsAccreditedSystem): + tags = get_accredited_system_tags(accredited_system=accredited_system_1.dict()) expected_tags = [ + {"nhs_id_code": "AAA", "nhs_as_svc_ia": "interaction-id-1"}, { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", + "nhs_id_code": "AAA", "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "ABC", "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - }, - { - "nhs_as_client": "CDE", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_manufacturer_org": "AAA", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", }, + {"nhs_id_code": "AAA", "nhs_as_svc_ia": "interaction-id-2"}, { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-2", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-1", - "nhs_mhs_manufacturer_org": "AAA", - "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "JKL", - "nhs_as_svc_ia": "interaction-id-4", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "EFG", - "nhs_as_svc_ia": "interaction-id-2", + "nhs_id_code": "AAA", "nhs_mhs_party_key": "AAA-123456", - }, - { - "nhs_as_client": "LMN", - "nhs_as_svc_ia": "interaction-id-2", - "nhs_mhs_party_key": "AAA-456789", - }, - { - "nhs_as_client": "ABC", - "nhs_as_svc_ia": "interaction-id-1", - }, - { - "nhs_as_client": "CDE", "nhs_as_svc_ia": "interaction-id-2", }, ] + for tag in tags: assert tag in expected_tags, f"{tag} not in expected tags" diff --git a/src/layers/sds/epr/tags/tags.py b/src/layers/sds/epr/tags/tags.py index fbd498915..5e97eed0c 100644 --- a/src/layers/sds/epr/tags/tags.py +++ b/src/layers/sds/epr/tags/tags.py @@ -16,7 +16,7 @@ from collections.abc import Iterable from itertools import product -from domain.api.sds.query import SearchSDSQueryParams +from domain.api.sds.query import SearchSDSDeviceQueryParams def _valid_tag_exists(tag_fields: set[str], data_fields: Iterable[str]) -> bool: @@ -47,7 +47,7 @@ def _generate_all_matching_queries( def sds_metadata_to_device_tags( - data: dict[str, str | Iterable], model: SearchSDSQueryParams + data: dict[str, str | Iterable], model: SearchSDSDeviceQueryParams ) -> list[tuple[tuple[str, str]]]: """ tldr; diff --git a/src/test_helpers/s3.py b/src/test_helpers/s3.py deleted file mode 100644 index 051c13b85..000000000 --- a/src/test_helpers/s3.py +++ /dev/null @@ -1,92 +0,0 @@ -from collections import deque -from json import JSONDecodeError -from types import FunctionType - -from botocore.exceptions import ClientError -from etl_utils.constants import ETL_QUEUE_HISTORY, ETL_STATE_MACHINE_HISTORY, WorkerKey -from etl_utils.io import pkl_dumps_lz4 -from mypy_boto3_s3 import S3Client - -from test_helpers.terraform import read_terraform_output - -TEST_DATA_NAME = "123.ldif" -EMPTY_LDIF_DATA = b"" -EMPTY_JSON_DATA = deque() -ALLOWED_EXCEPTIONS = (JSONDecodeError,) - - -def _ask_s3(s3_client: S3Client, bucket: str, key: str, question: FunctionType = None): - result = True - try: - response = s3_client.get_object(Bucket=bucket, Key=key) - except ClientError: - result = False - - if result and question is not None: - data = response["Body"].read() - try: - result = question(data) - except ALLOWED_EXCEPTIONS: - result = False - return result - - -def _ask_s3_prefix( - s3_client: S3Client, bucket: str, key_prefix: str, question: FunctionType = None -): - result = False - - response = s3_client.list_objects(Bucket=bucket, Prefix=key_prefix) - - for item in response.get("Contents", []): - if item and question is not None: - result = _ask_s3( - s3_client=s3_client, bucket=bucket, key=item["Key"], question=question - ) - return result - - -def _set_etl_content_config(): - bulk_trigger_prefix = read_terraform_output("sds_etl.value.bulk_trigger_prefix") - return { - "etl_bucket": read_terraform_output("sds_etl.value.bucket"), - "bulk_trigger_prefix": bulk_trigger_prefix, - "initial_trigger_key": f"{bulk_trigger_prefix}/{TEST_DATA_NAME}", - "queue_history_key_prefix": ETL_QUEUE_HISTORY, - "state_machine_history_key_prefix": ETL_STATE_MACHINE_HISTORY, - "table_name": read_terraform_output("dynamodb_table_name.value"), - } - - -def _set_etl_content(s3_client: S3Client, bucket_config: dict): - queue_history_key_prefix = bucket_config["queue_history_key_prefix"] - state_machine_history_key_prefix = bucket_config["state_machine_history_key_prefix"] - - # Clear/set the initial state - s3_client.put_object( - Bucket=bucket_config["etl_bucket"], Key=WorkerKey.EXTRACT, Body=EMPTY_LDIF_DATA - ) - s3_client.put_object( - Bucket=bucket_config["etl_bucket"], - Key=WorkerKey.TRANSFORM, - Body=pkl_dumps_lz4(EMPTY_JSON_DATA), - ) - s3_client.put_object( - Bucket=bucket_config["etl_bucket"], - Key=WorkerKey.LOAD, - Body=pkl_dumps_lz4(EMPTY_JSON_DATA), - ) - s3_client.delete_object( - Bucket=bucket_config["etl_bucket"], Key=bucket_config["initial_trigger_key"] - ) - queue_history_files = s3_client.list_objects( - Bucket=bucket_config["etl_bucket"], Prefix=f"{queue_history_key_prefix}/" - ) - for item in queue_history_files.get("Contents", []): - s3_client.delete_object(Bucket=bucket_config["etl_bucket"], Key=item["Key"]) - state_machine_history_files = s3_client.list_objects( - Bucket=bucket_config["etl_bucket"], - Prefix=f"{state_machine_history_key_prefix}/", - ) - for item in state_machine_history_files.get("Contents", []): - s3_client.delete_object(Bucket=bucket_config["etl_bucket"], Key=item["Key"])