Skip to content

[PRMP-1465] Post User Restriction#1131

Open
SWhyteAnswer wants to merge 40 commits intomainfrom
PRMP-1465
Open

[PRMP-1465] Post User Restriction#1131
SWhyteAnswer wants to merge 40 commits intomainfrom
PRMP-1465

Conversation

@SWhyteAnswer
Copy link
Contributor

@SWhyteAnswer SWhyteAnswer commented Feb 25, 2026

Overview

Jira ticket: TBC

Description

Context

Checklist

Tasks for all changes:

Additional tasks for UI changes (delete if not applicable):

  • 1. I have added evidence (to this PR) e.g. screenshots/gifs of all visual changes.

@override_error_check
@ensure_environment_variables(
names=[
"USER_RESTRICTIONS_TABLE_NAME",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double check this is the right var from the terraform

Comment on lines +30 to +52
body = event.get("body")
if not body:
logger.error("Missing request body")
return ApiGatewayResponse(
400, "Missing request body", "POST"
).create_api_gateway_response()

try:
payload = json.loads(body)
except json.JSONDecodeError as exc:
logger.error(exc)
return ApiGatewayResponse(
400, "Invalid request body", "POST"
).create_api_gateway_response()

# Required fields for creating a restriction.
smart_card_id = payload.get("smart_card_id")
nhs_number = payload.get("nhs_number")
if not smart_card_id or not nhs_number:
logger.error("Missing required fields")
return ApiGatewayResponse(
400, "Missing required fields", "POST"
).create_api_gateway_response()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be extracted into a separate function, parse_body?
think the body should always be valid JSON so might not need to handle this error
do we want a model to validate the request body against?
body will be coming from front end so probably camel case

Comment on lines +55 to +62
authorization = request_context.authorization or {}
creator = authorization.get("nhs_user_id")
ods_code = authorization.get("selected_organisation", {}).get("org_ods_code")
if not creator or not ods_code:
logger.error("Missing user context")
return ApiGatewayResponse(
400, "Missing user context", "POST"
).create_api_gateway_response()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could use the ods_util here, or create a new one that does both the creator and ods to be used with the other lambdas too?

creator: str,
) -> UserRestriction:
if smart_card_id == creator:
raise ValueError("You cannot create a restriction for yourself")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create custom exception

nhs_number=nhs_number,
custodian=ods_code,
creator=creator,
restricted_user_name=restricted_user_name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not on the model, no need to write to db

restriction = service.create_restriction(
smart_card_id=smart_card_id,
nhs_number=nhs_number,
ods_code=ods_code,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

custodian

raise ValueError("You cannot create a restriction for yourself")

practitioner = self.healthcare_service.get_practitioner(smart_card_id)
restricted_user_name = f"{practitioner.first_name} {practitioner.last_name}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

believe we are returning this the the frontend, may need to change what is returned from this function

Comment on lines +26 to +31
@pytest.fixture
def set_env(monkeypatch, set_env):
monkeypatch.setenv("USER_RESTRICTIONS_TABLE_NAME", MOCK_RESTRICTIONS_TABLE)
monkeypatch.setenv("HEALTHCARE_WORKER_API_URL", HEALTHCARE_WORKER_API_URL)
yield

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use conftest

Comment on lines +16 to +18
MOCK_SMART_CARD_ID = "smartcard-uuid-1234"
MOCK_CREATOR_ID = "creator-uuid-5678"
MOCK_RESTRICTIONS_TABLE = "test-user-restrictions-table"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conftest

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

Code security issues found

View full details here.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 5, 2026

"HEALTHCARE_WORKER_API_URL",
],
)
@handle_lambda_exceptions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add @validate patient id


restricted_smartcard_id, nhs_number = parse_body(event.get("body"))

patient_id = (event.get("queryStringParameters") or {}).get("patientId")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extract_nhs_number_from_event

Comment on lines +730 to +732
"""
Errors for UserRestriction lambda
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we make some of these more generic?

Comment on lines +28 to +31
raise CreateUserRestrictionLambdaException(
400,
LambdaError.CreateRestrictionMissingBody,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should raise a generic e.g "RequestError" and allow the handler to handle status code?

class CreateUserRestrictionService:
def __init__(self):
self.table_name = os.getenv("RESTRICTIONS_TABLE_NAME")
self.db_service = DynamoDBService()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use the user_restriction_dyanmodb_service from branch PRMP-1446? handles model validation etc for us

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be in user_restrictions dir

mock_request_context,
mock_user_restriction_enabled,
):
mock_service.create_restriction.return_value = "some-uuid"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use TEST_UUID here

Comment on lines +28 to +31
if restricted_smartcard_id == creator:
raise UserRestrictionException(
"You cannot create a restriction for yourself",
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the handler handle this?

restriction = UserRestriction(
restricted_user=restricted_smartcard_id,
nhs_number=nhs_number,
custodian=custodian,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to call PDS to validate the custodian here?

self.table_name = os.getenv("RESTRICTIONS_TABLE_NAME")
self.db_service = DynamoDBService()
self.healthcare_service = get_healthcare_worker_api_service()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before creating we need to check that there isn't an existing one for the patient/user

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you removing this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants