From 15899d12ea50b27378aa7867d9e2e2af5adfc1cd Mon Sep 17 00:00:00 2001 From: Adam Waller <176666249+adam-wallernhs1@users.noreply.github.com> Date: Tue, 30 Sep 2025 15:46:13 +0100 Subject: [PATCH 1/5] testing the protected main redo 2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b67ac523..8b22bfab 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Regression Tests](https://github.com/NHSDigital/eligibility-signposting-api-regression-tests/actions/workflows/regression_tests.yml/badge.svg?branch=main)](https://github.com/NHSDigital/eligibility-signposting-api-regression-tests/actions/workflows/regression_tests.yml) -# Regression Tests +# Regression Tests Adam These tests will automate End-to-End regression testing for: * [Eligibility Signposting API](https://github.com/NHSDigital/eligibility-signposting-api) From 73a35772d10eb67123a99fbdf7fe599c050eca65 Mon Sep 17 00:00:00 2001 From: Adam Waller <176666249+adam-wallernhs1@users.noreply.github.com> Date: Tue, 30 Sep 2025 15:52:20 +0100 Subject: [PATCH 2/5] testing the protected main undo 2 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b22bfab..b67ac523 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Regression Tests](https://github.com/NHSDigital/eligibility-signposting-api-regression-tests/actions/workflows/regression_tests.yml/badge.svg?branch=main)](https://github.com/NHSDigital/eligibility-signposting-api-regression-tests/actions/workflows/regression_tests.yml) -# Regression Tests Adam +# Regression Tests These tests will automate End-to-End regression testing for: * [Eligibility Signposting API](https://github.com/NHSDigital/eligibility-signposting-api) From 34365488e4e52153bb2e39136b22eb1699d278b7 Mon Sep 17 00:00:00 2001 From: Adam Waller <176666249+adam-wallernhs1@users.noreply.github.com> Date: Wed, 1 Oct 2025 09:36:36 +0100 Subject: [PATCH 3/5] -updated placeholder_utils.py so we can specify a replacement for an age tomorrow or yesterday - added TCs for ELI-426 - made a minor chnage to the vita integration test config to ensure virtual N was orking as expected --- .../storyTestConfigs/AUTO_RSV_ELI-426.json | 509 ++++++++++++++++++ .../vita_integration_test_config.json | 6 +- .../storyTestData/AUTO_RSV_ELI-426_001.json | 46 ++ .../storyTestData/AUTO_RSV_ELI-426_002.json | 46 ++ .../storyTestData/AUTO_RSV_ELI-426_003.json | 46 ++ .../storyTestData/AUTO_RSV_ELI-426_004.json | 46 ++ .../AUTO_RSV_ELI-426_001.json | 35 ++ .../AUTO_RSV_ELI-426_002.json | 37 ++ .../AUTO_RSV_ELI-426_003.json | 37 ++ .../AUTO_RSV_ELI-426_004.json | 35 ++ utils/placeholder_utils.py | 29 +- 11 files changed, 866 insertions(+), 6 deletions(-) create mode 100644 data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json diff --git a/data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json b/data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json new file mode 100644 index 00000000..43b0d81e --- /dev/null +++ b/data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json @@ -0,0 +1,509 @@ +{ + "CampaignConfig": { + "ID": "8fcb742b-45fa-4e0d-8f2f-9c2efb1f46d0", + "Version": 1, + "Name": "EliD RSV example config", + "Type": "V", + "Target": "RSV", + "Manager": [ + "example@nhs.net" + ], + "Approver": [ + "example@nhs.net" + ], + "Reviewer": [ + "example@nhs.net" + ], + "IterationFrequency": "X", + "IterationType": "O", + "IterationTime": "07:00:00", + "StartDate": "20250717", + "EndDate": "20350717", + "ApprovalMinimum": 0, + "ApprovalMaximum": 0, + "DefaultCommsRouting": "PLACEHOLDER_COMMS_ROUTING", + "Iterations": [ + { + "ID": "8fcb742b-45fa-4e0d-8f2f-9c2efb1f46d1", + "DefaultCommsRouting": "BOOK_LOCAL|HELP_SUPPORT", + "DefaultNotActionableRouting": "", + "DefaultNotEligibleRouting": "CHECK_CORRECT_X", + "Version": 1, + "Name": "EliD RSV example config", + "IterationDate": "20250717", + "IterationNumber": 1, + "CommsType": "I", + "ApprovalMinimum": 0, + "ApprovalMaximum": 0, + "Type": "O", + "IterationCohorts": [ + { + "CohortLabel": "rsv_75to79_plus1day", + "CohortGroup": "rsv_age", + "PositiveDescription": "are aged between 75 and 79", + "NegativeDescription": "are not aged 75 to 79", + "Priority": 0 + }, + { + "CohortLabel": "rsv_80_2024_plus1day", + "CohortGroup": "rsv_age_catchup", + "PositiveDescription": "turned 80 after 1st September 2024", + "NegativeDescription": "did not turn 80 after 1 September 2024", + "Priority": 10 + }, + { + "CohortLabel": "elid_all_people", + "CohortGroup": "magic_cohort", + "PositiveDescription": "", + "NegativeDescription": "", + "Priority": 20, + "Virtual": "Y" + } + ], + "IterationRules": [ + { + "Type": "F", + "Name": "Remove from magic cohort unless already vaccinated or have future booking", + "Description": "Remove anyone NOT already vaccinated within the last 25 years and do not have a future booking from the magic cohort", + "Operator": "Y<=", + "Comparator": "-25[[NVL:18000101]]", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "CohortLabel": "elid_all_people", + "Priority": 100 + }, + { + "Type": "F", + "Name": "Remove from magic cohort unless already vaccinated or have future booking", + "Description": "Remove anyone without a future booking from magic cohort", + "Operator": "D<", + "Comparator": "0[[NVL:18000101]]", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CohortLabel": "elid_all_people", + "Priority": 100 + }, + { + "Type": "F", + "Name": "Remove under 75 Years on day of execution", + "Description": "Ensure anyone who has a PDS date of birth which determines their age to be less than 75 years is filtered out.", + "Priority": 120, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-75", + "CohortLabel": "rsv_75to79_plus1day" + }, + { + "Type": "F", + "Name": "Remove anyone 80 or over on day of execution from the 75 to 79 cohort", + "Description": "Exclude anyone who turned 80 on the day", + "Priority": 130, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y<=", + "Comparator": "-80", + "CohortLabel": "rsv_75to79_plus1day" + }, + { + "Type": "F", + "Name": "Remove under 80 years on day of execution from the 80 since 2nd Sept 2024 cohort", + "Description": "Ensure anyone who has a PDS date of birth which determines their age to be less than 80 years is filtered out", + "Priority": 140, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-80", + "CohortLabel": "rsv_80_2024_plus1day" + }, + { + "Type": "F", + "Name": "Remove those over 80 before 2nd September 2024 from the 80 since 2nd Sept 2024 cohort", + "Description": "Exclude anyone who turned 80 before 2nd September 2024", + "Priority": 150, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "<", + "Comparator": "19440902", + "CohortLabel": "rsv_80_2024_plus1day" + }, + { + "Type": "F", + "Name": "Remove from rsv 80 cohort if already vaccinated", + "Description": "Remove anyone already vaccinated from 80 cohort", + "Operator": "Y>=", + "Comparator": "-25", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "CohortLabel": "rsv_80_2024_plus1day", + "Priority": 160 + }, + { + "Type": "F", + "Name": "Remove from rsv 80 cohort if future booking", + "Description": "Remove anyone with a future booking from RSV 80 cohort", + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CohortLabel": "rsv_80_2024_plus1day", + "Priority": 170 + }, + { + "Type": "F", + "Name": "Remove from rsv 75-79 cohort if already vaccinated", + "Description": "Remove anyone already vaccinated from 75-79 cohort", + "Operator": "Y>=", + "Comparator": "-25", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "CohortLabel": "rsv_75to79_plus1day", + "Priority": 180 + }, + { + "Type": "F", + "Name": "Remove from rsv 75-79 cohort if future booking", + "Description": "Remove anyone with a future booking from RSV 75-79 cohort", + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CohortLabel": "rsv_75to79_plus1day", + "Priority": 190 + }, + { + "Type": "S", + "Name": "Not Available", + "Description": "##RSV vaccinations are not currently available\n\nPlease try again soon.", + "Priority": 195, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658218997", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "NotYetDue", + "Description": "##Your RSV vaccination is not yet due\\n\\nYour next dose will be due in 3 months.", + "Priority": 196, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658219012", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "TooClose", + "Description": "##You have recently have the RSV vaccination\n\nYou must leave 90 days between doses of the RSV vaccine. Please try again soon.", + "Priority": 197, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658220142", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "EmptySuggestion", + "Description": "", + "Priority": 198, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658219004", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "AlreadyVaccinated", + "Description": "## You've had your RSV vaccination\n\nWe believe you were vaccinated against RSV on [[TARGET.RSV.LAST_SUCCESSFUL_DATE:DATE(%-d %B %Y)]].", + "Priority": 200, + "AttributeLevel": "TARGET", + "AttributeTarget": "RSV", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "Operator": "Y>=", + "Comparator": "-25", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 510, + "AttributeLevel": "PERSON", + "AttributeName": "CARE_HOME_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_80_2024_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 520, + "AttributeLevel": "PERSON", + "AttributeName": "DE_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_80_2024_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 530, + "AttributeLevel": "PERSON", + "AttributeName": "13Q_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_80_2024_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 540, + "AttributeLevel": "PERSON", + "AttributeName": "CARE_HOME_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_75to79_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 550, + "AttributeLevel": "PERSON", + "AttributeName": "DE_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_75to79_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 560, + "AttributeLevel": "PERSON", + "AttributeName": "13Q_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_75to79_plus1day", + "RuleStop": "Y" + }, + { + "Type": "R", + "Name": "Actionable Future Booked NBS Appointment", + "Description": "Amend NBS future booking", + "Priority": 1000, + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CommsRouting": "AMEND_NBS" + }, + { + "Type": "R", + "Name": "Actionable Future Booked NBS Appointment", + "Description": "Amend NBS future booking", + "Priority": 1000, + "Operator": "=", + "Comparator": "NBS", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_PROVIDER", + "CommsRouting": "AMEND_NBS" + }, + { + "Type": "R", + "Name": "Actionable Future Booked Local Appointment", + "Description": "Amend local future booking", + "Priority": 1100, + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CommsRouting": "MANAGE_LOCAL" + }, + { + "Type": "R", + "Name": "Within CP Expansion ICB not 80 plus", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1200, + "Operator": "in", + "Comparator": "QH8,QJG", + "AttributeLevel": "PERSON", + "AttributeName": "ICB", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "R", + "Name": "Within CP Expansion ICB not 80 plus", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1200, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-80", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "R", + "Name": "Within CP Expansion Local Authority", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1300, + "Operator": "in", + "Comparator": "E08000028,E08000031,E08000025,E06000016,E06000008,E07000117,E07000120,E08000011,E08000012,E07000122,E07000123,E08000014,E07000126,E08000013,E07000127,E08000015,E07000128", + "AttributeLevel": "PERSON", + "AttributeName": "LOCAL_AUTHORITY", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "R", + "Name": "Within CP Expansion ICB not 80 plus", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1300, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-80", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "Y", + "Name": "Already vaccinated default text", + "Description": "Already vaccinated default text", + "Priority": 3000, + "AttributeLevel": "TARGET", + "AttributeTarget": "RSV", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "Operator": "Y>=", + "Comparator": "-25", + "CommsRouting": "CHECK_CORRECT_ALREADY_VACCINATED" + }, + { + "Type": "Y", + "Name": "Other setting default text", + "Description": "Other setting default text", + "Priority": 3100, + "AttributeLevel": "PERSON", + "AttributeName": "CARE_HOME_FLAG", + "Operator": "=", + "Comparator": "Y", + "CommsRouting": "CHECK_CORRECT_OTHER_SETTING" + }, + { + "Type": "Y", + "Name": "Other setting default text", + "Description": "Other setting default text", + "Priority": 3200, + "AttributeLevel": "PERSON", + "AttributeName": "DE_FLAG", + "Operator": "=", + "Comparator": "Y", + "CommsRouting": "CHECK_CORRECT_OTHER_SETTING" + }, + { + "Type": "Y", + "Name": "Other setting default text", + "Description": "Other setting default text", + "Priority": 3300, + "AttributeLevel": "PERSON", + "AttributeName": "13Q_FLAG", + "Operator": "=", + "Comparator": "Y", + "CommsRouting": "CHECK_CORRECT_OTHER_SETTING" + } + ], + "ActionsMapper": { + "BOOK_NBS_INFO": { + "ExternalRoutingCode": "BookNBSInfoText", + "ActionDescription": "### Book an appointment online at a pharmacy\n\nYou can book an appointment online at a pharmacy that offers the RSV vaccination. You need to be registered with a GP to do this.", + "ActionType": "ButtonWithAuthLinkWithInfoText", + "UrlLink": "https://www.nhswebsite-staging.nhs.uk/nbs/nhs-app/vita/rsv", + "UrlLabel": "Continue to booking" + }, + "AMEND_NBS": { + "ExternalRoutingCode": "AmendNBS", + "ActionDescription": "## You have an RSV vaccination appointment booked\n\nYou can view, change or cancel your appointment below.", + "ActionType": "ButtonWithAuthLink", + "UrlLink": "https://www.nhswebsite-staging.nhs.uk/nbs/nhs-app/vita/rsv", + "UrlLabel": "Manage your appointment" + }, + "CONTACT_GP": { + "ExternalRoutingCode": "ContactGP", + "ActionDescription": "### Get vaccinated at your GP surgery\n\nContact your GP surgery to book an appointment.", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "BOOK_LOCAL": { + "ExternalRoutingCode": "BookLocal", + "ActionDescription": "### Getting the vaccine\n\nYou can get an RSV vaccination at your GP surgery.\n\nYour GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call, email or through the NHS App. You do not need to wait to be contacted before booking your vaccination.", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "MANAGE_LOCAL": { + "ExternalRoutingCode": "ManageLocal", + "ActionDescription": "## You have an RSV vaccination appointment booked\n\nTo change or cancel your appointment, contact the provider you booked with.", + "ActionType": "CardWithText", + "UrlLink": null, + "UrlLabel": "" + }, + "HELP_SUPPORT": { + "ExternalRoutingCode": "HelpSupportInfo", + "ActionDescription": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "CHECK_CORRECT_X": { + "ExternalRoutingCode": "HealthcareProInfo", + "ActionDescription": "### If this applies to you\n\nSpeak to your healthcare professional if you think you should be offered this vaccine.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "CHECK_CORRECT_ALREADY_VACCINATED": { + "ExternalRoutingCode": "AlreadyVaccinatedInfo", + "ActionDescription": "### If you think this is incorrect\n\nIf you believe you've not been vaccinated against RSV, speak to your healthcare professional.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "WALKIN": { + "ExternalRoutingCode": "WalkIn", + "ActionDescription": "### Get vaccinated without an appointment\n\nYou can get an RSV vaccination at some pharmacies without needing an appointment.\n\nYou do not need to be registered with a GP to do this.", + "ActionType": "ActionLinkWithInfoText", + "UrlLink": "https://www.nhs.uk/service-search/vaccination-and-booking-services/find-a-pharmacy-where-you-can-get-a-free-rsv-vaccination", + "UrlLabel": "Find a pharmacy where you can get a free RSV vaccination" + }, + "CHECK_CORRECT_OTHER_SETTING": { + "ExternalRoutingCode": "ManagedSettingInfo", + "ActionDescription": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page] (https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + } + } + } + ] + } +} diff --git a/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json b/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json index 43b0d81e..781550f0 100644 --- a/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json +++ b/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json @@ -42,14 +42,16 @@ "CohortGroup": "rsv_age", "PositiveDescription": "are aged between 75 and 79", "NegativeDescription": "are not aged 75 to 79", - "Priority": 0 + "Priority": 0, + "Virtual": "N" }, { "CohortLabel": "rsv_80_2024_plus1day", "CohortGroup": "rsv_age_catchup", "PositiveDescription": "turned 80 after 1st September 2024", "NegativeDescription": "did not turn 80 after 1 September 2024", - "Priority": 10 + "Priority": 10, + "Virtual": "N" }, { "CohortLabel": "elid_all_people", diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json new file mode 100644 index 00000000..7ad0cee6 --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-001 - NotEligible - 75 Tomorrow so Filtered out", + "request_headers": { + "nhs-login-nhs-number": "9900426001" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426001", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426001", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426001", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json new file mode 100644 index 00000000..72aba228 --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-002 - Actionable - 75 Today and in rsv_75to79_plus1day", + "request_headers": { + "nhs-login-nhs-number": "9900426002" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426002", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426002", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426002", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json new file mode 100644 index 00000000..ef2d59da --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-003 - Actionable - 80 Tomorrow and in rsv_75to79_plus1day", + "request_headers": { + "nhs-login-nhs-number": "9900426003" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426003", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426003", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426003", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json new file mode 100644 index 00000000..ad241291 --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-004 - NotEligible - 80 Today and in rsv_75to79_plus1day", + "request_headers": { + "nhs-login-nhs-number": "9900426004" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426004", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426004", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426004", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json new file mode 100644 index 00000000..67397086 --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json @@ -0,0 +1,35 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:52:16.108007+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "HealthcareProInfo", + "actionType": "InfoText", + "description": "### If this applies to you\n\nSpeak to your healthcare professional if you think you should be offered this vaccine.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "NotEligible", + "cohortText": "are not aged 75 to 79" + }, + { + "cohortCode": "rsv_age_catchup", + "cohortStatus": "NotEligible", + "cohortText": "did not turn 80 after 1 September 2024" + } + ], + "status": "NotEligible", + "statusText": "We do not believe you can have it", + "suitabilityRules": [] + } + ], + "responseId": "cb3ad66b-f59f-461d-9f46-0e31edf944f9" +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json new file mode 100644 index 00000000..bd3a77ae --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json @@ -0,0 +1,37 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:59:20.009716+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "BookLocal", + "actionType": "InfoText", + "description": "### Getting the vaccine\n\nYou can get an RSV vaccination at your GP surgery.\n\nYour GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call, email or through the NHS App. You do not need to wait to be contacted before booking your vaccination.", + "urlLabel": "", + "urlLink": "" + }, + { + "actionCode": "HelpSupportInfo", + "actionType": "InfoText", + "description": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "Actionable", + "cohortText": "are aged between 75 and 79" + } + ], + "status": "Actionable", + "statusText": "You should have the RSV vaccine", + "suitabilityRules": [] + } + ], + "responseId": "efdea5ac-ba1b-448f-9d63-6691265417ee" +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json new file mode 100644 index 00000000..bd3a77ae --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json @@ -0,0 +1,37 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:59:20.009716+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "BookLocal", + "actionType": "InfoText", + "description": "### Getting the vaccine\n\nYou can get an RSV vaccination at your GP surgery.\n\nYour GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call, email or through the NHS App. You do not need to wait to be contacted before booking your vaccination.", + "urlLabel": "", + "urlLink": "" + }, + { + "actionCode": "HelpSupportInfo", + "actionType": "InfoText", + "description": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "Actionable", + "cohortText": "are aged between 75 and 79" + } + ], + "status": "Actionable", + "statusText": "You should have the RSV vaccine", + "suitabilityRules": [] + } + ], + "responseId": "efdea5ac-ba1b-448f-9d63-6691265417ee" +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json new file mode 100644 index 00000000..67397086 --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json @@ -0,0 +1,35 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:52:16.108007+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "HealthcareProInfo", + "actionType": "InfoText", + "description": "### If this applies to you\n\nSpeak to your healthcare professional if you think you should be offered this vaccine.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "NotEligible", + "cohortText": "are not aged 75 to 79" + }, + { + "cohortCode": "rsv_age_catchup", + "cohortStatus": "NotEligible", + "cohortText": "did not turn 80 after 1 September 2024" + } + ], + "status": "NotEligible", + "statusText": "We do not believe you can have it", + "suitabilityRules": [] + } + ], + "responseId": "cb3ad66b-f59f-461d-9f46-0e31edf944f9" +} diff --git a/utils/placeholder_utils.py b/utils/placeholder_utils.py index 7dab8990..40486a2d 100644 --- a/utils/placeholder_utils.py +++ b/utils/placeholder_utils.py @@ -34,7 +34,6 @@ def replacer(match): def _resolve_placeholder_value(placeholder: str) -> str: placeholder_parts_length = 3 - # RDATE valid_placeholder_types = ["DATE", "RDATE", "IGNORE"] result = f"<<{placeholder}>>" # Default fallback @@ -53,7 +52,7 @@ def _resolve_placeholder_value(placeholder: str) -> str: try: if date_type == "AGE": - result = _resolve_age_placeholder(today, int(arg), parts[0]) + result = _resolve_age_placeholder(today, arg, parts[0]) elif date_type == "DAY": result = _format_date(today + timedelta(days=int(arg)), parts[0]) elif date_type == "WEEK": @@ -68,8 +67,26 @@ def _resolve_placeholder_value(placeholder: str) -> str: return result -def _resolve_age_placeholder(today: datetime, years_back: int, format_type: str) -> str: - target_year = today.year - years_back +def _resolve_age_placeholder(today: datetime, age_str: str, format_type: str) -> str: + """ + Resolve placeholders like: + - RDATE_AGE_65 + - RDATE_AGE_65-TOMORROW + - RDATE_AGE_65-YESTERDAY + """ + + offset_days = 0 + + if age_str.endswith("-TOMORROW"): + age = int(age_str.replace("-TOMORROW", "")) + offset_days = 1 + elif age_str.endswith("-YESTERDAY"): + age = int(age_str.replace("-YESTERDAY", "")) + offset_days = -1 + else: + age = int(age_str) + + target_year = today.year - age february = 2 leap_year_day = 29 try: @@ -83,6 +100,10 @@ def _resolve_age_placeholder(today: datetime, years_back: int, format_type: str) result_date = datetime(target_year, 2, 28, tzinfo=UTC) else: raise + + if offset_days: + result_date = result_date + timedelta(days=offset_days) + return _format_date(result_date, format_type) From b2b7ec3a03c0d97f44b6fe07abfda1fa2cc8d535 Mon Sep 17 00:00:00 2001 From: Adam Waller <176666249+adam-wallernhs1@users.noreply.github.com> Date: Wed, 1 Oct 2025 09:36:36 +0100 Subject: [PATCH 4/5] -updated placeholder_utils.py so we can specify a replacement for an age tomorrow or yesterday - added TCs for ELI-426 - made a minor change to the vita integration test config to ensure virtual N was working as expected --- .../storyTestConfigs/AUTO_RSV_ELI-426.json | 509 ++++++++++++++++++ .../vita_integration_test_config.json | 6 +- .../storyTestData/AUTO_RSV_ELI-426_001.json | 46 ++ .../storyTestData/AUTO_RSV_ELI-426_002.json | 46 ++ .../storyTestData/AUTO_RSV_ELI-426_003.json | 46 ++ .../storyTestData/AUTO_RSV_ELI-426_004.json | 46 ++ .../AUTO_RSV_ELI-426_001.json | 35 ++ .../AUTO_RSV_ELI-426_002.json | 37 ++ .../AUTO_RSV_ELI-426_003.json | 37 ++ .../AUTO_RSV_ELI-426_004.json | 35 ++ utils/placeholder_utils.py | 29 +- 11 files changed, 866 insertions(+), 6 deletions(-) create mode 100644 data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json create mode 100644 data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json create mode 100644 data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json diff --git a/data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json b/data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json new file mode 100644 index 00000000..43b0d81e --- /dev/null +++ b/data/configs/storyTestConfigs/AUTO_RSV_ELI-426.json @@ -0,0 +1,509 @@ +{ + "CampaignConfig": { + "ID": "8fcb742b-45fa-4e0d-8f2f-9c2efb1f46d0", + "Version": 1, + "Name": "EliD RSV example config", + "Type": "V", + "Target": "RSV", + "Manager": [ + "example@nhs.net" + ], + "Approver": [ + "example@nhs.net" + ], + "Reviewer": [ + "example@nhs.net" + ], + "IterationFrequency": "X", + "IterationType": "O", + "IterationTime": "07:00:00", + "StartDate": "20250717", + "EndDate": "20350717", + "ApprovalMinimum": 0, + "ApprovalMaximum": 0, + "DefaultCommsRouting": "PLACEHOLDER_COMMS_ROUTING", + "Iterations": [ + { + "ID": "8fcb742b-45fa-4e0d-8f2f-9c2efb1f46d1", + "DefaultCommsRouting": "BOOK_LOCAL|HELP_SUPPORT", + "DefaultNotActionableRouting": "", + "DefaultNotEligibleRouting": "CHECK_CORRECT_X", + "Version": 1, + "Name": "EliD RSV example config", + "IterationDate": "20250717", + "IterationNumber": 1, + "CommsType": "I", + "ApprovalMinimum": 0, + "ApprovalMaximum": 0, + "Type": "O", + "IterationCohorts": [ + { + "CohortLabel": "rsv_75to79_plus1day", + "CohortGroup": "rsv_age", + "PositiveDescription": "are aged between 75 and 79", + "NegativeDescription": "are not aged 75 to 79", + "Priority": 0 + }, + { + "CohortLabel": "rsv_80_2024_plus1day", + "CohortGroup": "rsv_age_catchup", + "PositiveDescription": "turned 80 after 1st September 2024", + "NegativeDescription": "did not turn 80 after 1 September 2024", + "Priority": 10 + }, + { + "CohortLabel": "elid_all_people", + "CohortGroup": "magic_cohort", + "PositiveDescription": "", + "NegativeDescription": "", + "Priority": 20, + "Virtual": "Y" + } + ], + "IterationRules": [ + { + "Type": "F", + "Name": "Remove from magic cohort unless already vaccinated or have future booking", + "Description": "Remove anyone NOT already vaccinated within the last 25 years and do not have a future booking from the magic cohort", + "Operator": "Y<=", + "Comparator": "-25[[NVL:18000101]]", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "CohortLabel": "elid_all_people", + "Priority": 100 + }, + { + "Type": "F", + "Name": "Remove from magic cohort unless already vaccinated or have future booking", + "Description": "Remove anyone without a future booking from magic cohort", + "Operator": "D<", + "Comparator": "0[[NVL:18000101]]", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CohortLabel": "elid_all_people", + "Priority": 100 + }, + { + "Type": "F", + "Name": "Remove under 75 Years on day of execution", + "Description": "Ensure anyone who has a PDS date of birth which determines their age to be less than 75 years is filtered out.", + "Priority": 120, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-75", + "CohortLabel": "rsv_75to79_plus1day" + }, + { + "Type": "F", + "Name": "Remove anyone 80 or over on day of execution from the 75 to 79 cohort", + "Description": "Exclude anyone who turned 80 on the day", + "Priority": 130, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y<=", + "Comparator": "-80", + "CohortLabel": "rsv_75to79_plus1day" + }, + { + "Type": "F", + "Name": "Remove under 80 years on day of execution from the 80 since 2nd Sept 2024 cohort", + "Description": "Ensure anyone who has a PDS date of birth which determines their age to be less than 80 years is filtered out", + "Priority": 140, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-80", + "CohortLabel": "rsv_80_2024_plus1day" + }, + { + "Type": "F", + "Name": "Remove those over 80 before 2nd September 2024 from the 80 since 2nd Sept 2024 cohort", + "Description": "Exclude anyone who turned 80 before 2nd September 2024", + "Priority": 150, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "<", + "Comparator": "19440902", + "CohortLabel": "rsv_80_2024_plus1day" + }, + { + "Type": "F", + "Name": "Remove from rsv 80 cohort if already vaccinated", + "Description": "Remove anyone already vaccinated from 80 cohort", + "Operator": "Y>=", + "Comparator": "-25", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "CohortLabel": "rsv_80_2024_plus1day", + "Priority": 160 + }, + { + "Type": "F", + "Name": "Remove from rsv 80 cohort if future booking", + "Description": "Remove anyone with a future booking from RSV 80 cohort", + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CohortLabel": "rsv_80_2024_plus1day", + "Priority": 170 + }, + { + "Type": "F", + "Name": "Remove from rsv 75-79 cohort if already vaccinated", + "Description": "Remove anyone already vaccinated from 75-79 cohort", + "Operator": "Y>=", + "Comparator": "-25", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "CohortLabel": "rsv_75to79_plus1day", + "Priority": 180 + }, + { + "Type": "F", + "Name": "Remove from rsv 75-79 cohort if future booking", + "Description": "Remove anyone with a future booking from RSV 75-79 cohort", + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CohortLabel": "rsv_75to79_plus1day", + "Priority": 190 + }, + { + "Type": "S", + "Name": "Not Available", + "Description": "##RSV vaccinations are not currently available\n\nPlease try again soon.", + "Priority": 195, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658218997", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "NotYetDue", + "Description": "##Your RSV vaccination is not yet due\\n\\nYour next dose will be due in 3 months.", + "Priority": 196, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658219012", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "TooClose", + "Description": "##You have recently have the RSV vaccination\n\nYou must leave 90 days between doses of the RSV vaccine. Please try again soon.", + "Priority": 197, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658220142", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "EmptySuggestion", + "Description": "", + "Priority": 198, + "AttributeLevel": "PERSON", + "AttributeName": "NHS_NUMBER", + "Operator": "=", + "Comparator": "9658219004", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "AlreadyVaccinated", + "Description": "## You've had your RSV vaccination\n\nWe believe you were vaccinated against RSV on [[TARGET.RSV.LAST_SUCCESSFUL_DATE:DATE(%-d %B %Y)]].", + "Priority": 200, + "AttributeLevel": "TARGET", + "AttributeTarget": "RSV", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "Operator": "Y>=", + "Comparator": "-25", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 510, + "AttributeLevel": "PERSON", + "AttributeName": "CARE_HOME_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_80_2024_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 520, + "AttributeLevel": "PERSON", + "AttributeName": "DE_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_80_2024_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 530, + "AttributeLevel": "PERSON", + "AttributeName": "13Q_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_80_2024_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 540, + "AttributeLevel": "PERSON", + "AttributeName": "CARE_HOME_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_75to79_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 550, + "AttributeLevel": "PERSON", + "AttributeName": "DE_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_75to79_plus1day", + "RuleStop": "Y" + }, + { + "Type": "S", + "Name": "OtherSetting", + "Description": "### Getting the vaccine\n\nWe believe you live in a setting where care is provided.\n\nSpeak to a member of staff where you live about getting the RSV vaccine.", + "Priority": 560, + "AttributeLevel": "PERSON", + "AttributeName": "13Q_FLAG", + "Operator": "=", + "Comparator": "Y", + "CohortLabel": "rsv_75to79_plus1day", + "RuleStop": "Y" + }, + { + "Type": "R", + "Name": "Actionable Future Booked NBS Appointment", + "Description": "Amend NBS future booking", + "Priority": 1000, + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CommsRouting": "AMEND_NBS" + }, + { + "Type": "R", + "Name": "Actionable Future Booked NBS Appointment", + "Description": "Amend NBS future booking", + "Priority": 1000, + "Operator": "=", + "Comparator": "NBS", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_PROVIDER", + "CommsRouting": "AMEND_NBS" + }, + { + "Type": "R", + "Name": "Actionable Future Booked Local Appointment", + "Description": "Amend local future booking", + "Priority": 1100, + "Operator": "D>=", + "Comparator": "0", + "AttributeTarget": "RSV", + "AttributeLevel": "TARGET", + "AttributeName": "BOOKED_APPOINTMENT_DATE", + "CommsRouting": "MANAGE_LOCAL" + }, + { + "Type": "R", + "Name": "Within CP Expansion ICB not 80 plus", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1200, + "Operator": "in", + "Comparator": "QH8,QJG", + "AttributeLevel": "PERSON", + "AttributeName": "ICB", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "R", + "Name": "Within CP Expansion ICB not 80 plus", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1200, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-80", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "R", + "Name": "Within CP Expansion Local Authority", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1300, + "Operator": "in", + "Comparator": "E08000028,E08000031,E08000025,E06000016,E06000008,E07000117,E07000120,E08000011,E08000012,E07000122,E07000123,E08000014,E07000126,E08000013,E07000127,E08000015,E07000128", + "AttributeLevel": "PERSON", + "AttributeName": "LOCAL_AUTHORITY", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "R", + "Name": "Within CP Expansion ICB not 80 plus", + "Description": "Book an appointment on NBS as within CP expansion", + "Priority": 1300, + "AttributeLevel": "PERSON", + "AttributeName": "DATE_OF_BIRTH", + "Operator": "Y>", + "Comparator": "-80", + "CommsRouting": "CONTACT_GP|BOOK_NBS_INFO|WALKIN|HELP_SUPPORT" + }, + { + "Type": "Y", + "Name": "Already vaccinated default text", + "Description": "Already vaccinated default text", + "Priority": 3000, + "AttributeLevel": "TARGET", + "AttributeTarget": "RSV", + "AttributeName": "LAST_SUCCESSFUL_DATE", + "Operator": "Y>=", + "Comparator": "-25", + "CommsRouting": "CHECK_CORRECT_ALREADY_VACCINATED" + }, + { + "Type": "Y", + "Name": "Other setting default text", + "Description": "Other setting default text", + "Priority": 3100, + "AttributeLevel": "PERSON", + "AttributeName": "CARE_HOME_FLAG", + "Operator": "=", + "Comparator": "Y", + "CommsRouting": "CHECK_CORRECT_OTHER_SETTING" + }, + { + "Type": "Y", + "Name": "Other setting default text", + "Description": "Other setting default text", + "Priority": 3200, + "AttributeLevel": "PERSON", + "AttributeName": "DE_FLAG", + "Operator": "=", + "Comparator": "Y", + "CommsRouting": "CHECK_CORRECT_OTHER_SETTING" + }, + { + "Type": "Y", + "Name": "Other setting default text", + "Description": "Other setting default text", + "Priority": 3300, + "AttributeLevel": "PERSON", + "AttributeName": "13Q_FLAG", + "Operator": "=", + "Comparator": "Y", + "CommsRouting": "CHECK_CORRECT_OTHER_SETTING" + } + ], + "ActionsMapper": { + "BOOK_NBS_INFO": { + "ExternalRoutingCode": "BookNBSInfoText", + "ActionDescription": "### Book an appointment online at a pharmacy\n\nYou can book an appointment online at a pharmacy that offers the RSV vaccination. You need to be registered with a GP to do this.", + "ActionType": "ButtonWithAuthLinkWithInfoText", + "UrlLink": "https://www.nhswebsite-staging.nhs.uk/nbs/nhs-app/vita/rsv", + "UrlLabel": "Continue to booking" + }, + "AMEND_NBS": { + "ExternalRoutingCode": "AmendNBS", + "ActionDescription": "## You have an RSV vaccination appointment booked\n\nYou can view, change or cancel your appointment below.", + "ActionType": "ButtonWithAuthLink", + "UrlLink": "https://www.nhswebsite-staging.nhs.uk/nbs/nhs-app/vita/rsv", + "UrlLabel": "Manage your appointment" + }, + "CONTACT_GP": { + "ExternalRoutingCode": "ContactGP", + "ActionDescription": "### Get vaccinated at your GP surgery\n\nContact your GP surgery to book an appointment.", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "BOOK_LOCAL": { + "ExternalRoutingCode": "BookLocal", + "ActionDescription": "### Getting the vaccine\n\nYou can get an RSV vaccination at your GP surgery.\n\nYour GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call, email or through the NHS App. You do not need to wait to be contacted before booking your vaccination.", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "MANAGE_LOCAL": { + "ExternalRoutingCode": "ManageLocal", + "ActionDescription": "## You have an RSV vaccination appointment booked\n\nTo change or cancel your appointment, contact the provider you booked with.", + "ActionType": "CardWithText", + "UrlLink": null, + "UrlLabel": "" + }, + "HELP_SUPPORT": { + "ExternalRoutingCode": "HelpSupportInfo", + "ActionDescription": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "CHECK_CORRECT_X": { + "ExternalRoutingCode": "HealthcareProInfo", + "ActionDescription": "### If this applies to you\n\nSpeak to your healthcare professional if you think you should be offered this vaccine.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "CHECK_CORRECT_ALREADY_VACCINATED": { + "ExternalRoutingCode": "AlreadyVaccinatedInfo", + "ActionDescription": "### If you think this is incorrect\n\nIf you believe you've not been vaccinated against RSV, speak to your healthcare professional.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + }, + "WALKIN": { + "ExternalRoutingCode": "WalkIn", + "ActionDescription": "### Get vaccinated without an appointment\n\nYou can get an RSV vaccination at some pharmacies without needing an appointment.\n\nYou do not need to be registered with a GP to do this.", + "ActionType": "ActionLinkWithInfoText", + "UrlLink": "https://www.nhs.uk/service-search/vaccination-and-booking-services/find-a-pharmacy-where-you-can-get-a-free-rsv-vaccination", + "UrlLabel": "Find a pharmacy where you can get a free RSV vaccination" + }, + "CHECK_CORRECT_OTHER_SETTING": { + "ExternalRoutingCode": "ManagedSettingInfo", + "ActionDescription": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page] (https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "ActionType": "InfoText", + "UrlLink": null, + "UrlLabel": "" + } + } + } + ] + } +} diff --git a/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json b/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json index 43b0d81e..781550f0 100644 --- a/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json +++ b/data/configs/vitaIntegrationTestConfigs/vita_integration_test_config.json @@ -42,14 +42,16 @@ "CohortGroup": "rsv_age", "PositiveDescription": "are aged between 75 and 79", "NegativeDescription": "are not aged 75 to 79", - "Priority": 0 + "Priority": 0, + "Virtual": "N" }, { "CohortLabel": "rsv_80_2024_plus1day", "CohortGroup": "rsv_age_catchup", "PositiveDescription": "turned 80 after 1st September 2024", "NegativeDescription": "did not turn 80 after 1 September 2024", - "Priority": 10 + "Priority": 10, + "Virtual": "N" }, { "CohortLabel": "elid_all_people", diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json new file mode 100644 index 00000000..7ad0cee6 --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_001.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-001 - NotEligible - 75 Tomorrow so Filtered out", + "request_headers": { + "nhs-login-nhs-number": "9900426001" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426001", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426001", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426001", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json new file mode 100644 index 00000000..72aba228 --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_002.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-002 - Actionable - 75 Today and in rsv_75to79_plus1day", + "request_headers": { + "nhs-login-nhs-number": "9900426002" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426002", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426002", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426002", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json new file mode 100644 index 00000000..ef2d59da --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_003.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-003 - Actionable - 80 Tomorrow and in rsv_75to79_plus1day", + "request_headers": { + "nhs-login-nhs-number": "9900426003" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426003", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426003", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426003", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json new file mode 100644 index 00000000..ad241291 --- /dev/null +++ b/data/dynamoDB/storyTestData/AUTO_RSV_ELI-426_004.json @@ -0,0 +1,46 @@ +{ + "scenario_name": "ELI-426-004 - NotEligible - 80 Today and in rsv_75to79_plus1day", + "request_headers": { + "nhs-login-nhs-number": "9900426004" + }, + "config_filenames": [ + "AUTO_RSV_ELI-426.json" + ], + "data": [ + { + "NHS_NUMBER": "9900426004", + "ATTRIBUTE_TYPE": "COHORTS", + "COHORT_MEMBERSHIPS": [ + { + "COHORT_LABEL": "rsv_75to79_plus1day", + "DATE_JOINED": "20231020" + } + ] + }, + { + "NHS_NUMBER": "9900426004", + "ATTRIBUTE_TYPE": "PERSON", + "DATE_OF_BIRTH": "<>", + "GENDER": "0", + "POSTCODE": "SG8 6EG", + "POSTCODE_SECTOR": "SG86", + "POSTCODE_OUTCODE": "SG8", + "MSOA": "E02003792", + "LSOA": "E01018267", + "GP_PRACTICE_CODE": "D81046", + "PCN": "U75549", + "ICB": "QUE", + "COMMISSIONING_REGION": "Y61", + "13Q_FLAG": "N", + "CARE_HOME_FLAG": "N", + "DE_FLAG": "N" + }, + { + "NHS_NUMBER": "9900426004", + "ATTRIBUTE_TYPE": "RSV", + "LAST_SUCCESSFUL_DATE": null, + "BOOKED_APPOINTMENT_DATE": null, + "BOOKED_APPOINTMENT_PROVIDER": null + } + ] +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json new file mode 100644 index 00000000..67397086 --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_001.json @@ -0,0 +1,35 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:52:16.108007+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "HealthcareProInfo", + "actionType": "InfoText", + "description": "### If this applies to you\n\nSpeak to your healthcare professional if you think you should be offered this vaccine.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "NotEligible", + "cohortText": "are not aged 75 to 79" + }, + { + "cohortCode": "rsv_age_catchup", + "cohortStatus": "NotEligible", + "cohortText": "did not turn 80 after 1 September 2024" + } + ], + "status": "NotEligible", + "statusText": "We do not believe you can have it", + "suitabilityRules": [] + } + ], + "responseId": "cb3ad66b-f59f-461d-9f46-0e31edf944f9" +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json new file mode 100644 index 00000000..bd3a77ae --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_002.json @@ -0,0 +1,37 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:59:20.009716+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "BookLocal", + "actionType": "InfoText", + "description": "### Getting the vaccine\n\nYou can get an RSV vaccination at your GP surgery.\n\nYour GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call, email or through the NHS App. You do not need to wait to be contacted before booking your vaccination.", + "urlLabel": "", + "urlLink": "" + }, + { + "actionCode": "HelpSupportInfo", + "actionType": "InfoText", + "description": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "Actionable", + "cohortText": "are aged between 75 and 79" + } + ], + "status": "Actionable", + "statusText": "You should have the RSV vaccine", + "suitabilityRules": [] + } + ], + "responseId": "efdea5ac-ba1b-448f-9d63-6691265417ee" +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json new file mode 100644 index 00000000..bd3a77ae --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_003.json @@ -0,0 +1,37 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:59:20.009716+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "BookLocal", + "actionType": "InfoText", + "description": "### Getting the vaccine\n\nYou can get an RSV vaccination at your GP surgery.\n\nYour GP surgery may contact you about getting the RSV vaccine. This may be by letter, text, phone call, email or through the NHS App. You do not need to wait to be contacted before booking your vaccination.", + "urlLabel": "", + "urlLink": "" + }, + { + "actionCode": "HelpSupportInfo", + "actionType": "InfoText", + "description": "### If you think this is incorrect\n\nIf you have already had this vaccination or your personal details are wrong, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "Actionable", + "cohortText": "are aged between 75 and 79" + } + ], + "status": "Actionable", + "statusText": "You should have the RSV vaccine", + "suitabilityRules": [] + } + ], + "responseId": "efdea5ac-ba1b-448f-9d63-6691265417ee" +} diff --git a/data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json new file mode 100644 index 00000000..67397086 --- /dev/null +++ b/data/responses/storyTestResponses/AUTO_RSV_ELI-426_004.json @@ -0,0 +1,35 @@ +{ + "meta": { + "lastUpdated": "2025-09-30T15:52:16.108007+00:00" + }, + "processedSuggestions": [ + { + "actions": [ + { + "actionCode": "HealthcareProInfo", + "actionType": "InfoText", + "description": "### If this applies to you\n\nSpeak to your healthcare professional if you think you should be offered this vaccine.\n\nFor anything else, visit our [help and support page](https://www.nhs.uk/nhs-app/nhs-app-help-and-support/).", + "urlLabel": "", + "urlLink": "" + } + ], + "condition": "RSV", + "eligibilityCohorts": [ + { + "cohortCode": "rsv_age", + "cohortStatus": "NotEligible", + "cohortText": "are not aged 75 to 79" + }, + { + "cohortCode": "rsv_age_catchup", + "cohortStatus": "NotEligible", + "cohortText": "did not turn 80 after 1 September 2024" + } + ], + "status": "NotEligible", + "statusText": "We do not believe you can have it", + "suitabilityRules": [] + } + ], + "responseId": "cb3ad66b-f59f-461d-9f46-0e31edf944f9" +} diff --git a/utils/placeholder_utils.py b/utils/placeholder_utils.py index 7dab8990..40486a2d 100644 --- a/utils/placeholder_utils.py +++ b/utils/placeholder_utils.py @@ -34,7 +34,6 @@ def replacer(match): def _resolve_placeholder_value(placeholder: str) -> str: placeholder_parts_length = 3 - # RDATE valid_placeholder_types = ["DATE", "RDATE", "IGNORE"] result = f"<<{placeholder}>>" # Default fallback @@ -53,7 +52,7 @@ def _resolve_placeholder_value(placeholder: str) -> str: try: if date_type == "AGE": - result = _resolve_age_placeholder(today, int(arg), parts[0]) + result = _resolve_age_placeholder(today, arg, parts[0]) elif date_type == "DAY": result = _format_date(today + timedelta(days=int(arg)), parts[0]) elif date_type == "WEEK": @@ -68,8 +67,26 @@ def _resolve_placeholder_value(placeholder: str) -> str: return result -def _resolve_age_placeholder(today: datetime, years_back: int, format_type: str) -> str: - target_year = today.year - years_back +def _resolve_age_placeholder(today: datetime, age_str: str, format_type: str) -> str: + """ + Resolve placeholders like: + - RDATE_AGE_65 + - RDATE_AGE_65-TOMORROW + - RDATE_AGE_65-YESTERDAY + """ + + offset_days = 0 + + if age_str.endswith("-TOMORROW"): + age = int(age_str.replace("-TOMORROW", "")) + offset_days = 1 + elif age_str.endswith("-YESTERDAY"): + age = int(age_str.replace("-YESTERDAY", "")) + offset_days = -1 + else: + age = int(age_str) + + target_year = today.year - age february = 2 leap_year_day = 29 try: @@ -83,6 +100,10 @@ def _resolve_age_placeholder(today: datetime, years_back: int, format_type: str) result_date = datetime(target_year, 2, 28, tzinfo=UTC) else: raise + + if offset_days: + result_date = result_date + timedelta(days=offset_days) + return _format_date(result_date, format_type) From b4e0698820cd34eea579a2f531c0489a3ad2c525 Mon Sep 17 00:00:00 2001 From: Adam Waller <176666249+adam-wallernhs1@users.noreply.github.com> Date: Thu, 2 Oct 2025 10:41:15 +0100 Subject: [PATCH 5/5] - an update to the comments only --- utils/placeholder_utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/placeholder_utils.py b/utils/placeholder_utils.py index 40486a2d..35f2ffe7 100644 --- a/utils/placeholder_utils.py +++ b/utils/placeholder_utils.py @@ -70,9 +70,9 @@ def _resolve_placeholder_value(placeholder: str) -> str: def _resolve_age_placeholder(today: datetime, age_str: str, format_type: str) -> str: """ Resolve placeholders like: - - RDATE_AGE_65 - - RDATE_AGE_65-TOMORROW - - RDATE_AGE_65-YESTERDAY + - DATE_AGE_75 + - DATE_AGE_75-TOMORROW + - DATE_AGE_75-YESTERDAY """ offset_days = 0