Skip to content

Commit 3ae4044

Browse files
iteration validation
1 parent a679ece commit 3ae4044

3 files changed

Lines changed: 14 additions & 301 deletions

File tree

src/rules_validation_api/campaign_config.json

Lines changed: 0 additions & 296 deletions
Original file line numberDiff line numberDiff line change
@@ -314,302 +314,6 @@
314314
"ActionType": "button"
315315
}
316316
}
317-
},
318-
{
319-
"ID": "<<RANDOM_GUID>>_iteration_random_guid1",
320-
"DefaultCommsRouting": "BOOK_LOCAL",
321-
"DefaultNotActionableRouting": "INTERNALCONTACTGP1",
322-
"DefaultNotEligibleRouting": "INTERNALCONTACTGP1",
323-
"Version": "1",
324-
"Name": "Automation RSV - Smoke Test Config Iteration",
325-
"IterationDate": "20250601",
326-
"IterationNumber": 1,
327-
"CommsType": "I",
328-
"ApprovalMinimum": 0,
329-
"ApprovalMaximum": 0,
330-
"Type": "O",
331-
"IterationCohorts":
332-
[
333-
{
334-
"CohortLabel": "rsv_75_rolling",
335-
"CohortGroup": "rsv_age_rolling",
336-
"PositiveDescription": "are aged 75 to 79 years old.",
337-
"NegativeDescription": "are not aged 75 to 79 years old.",
338-
"Priority": 0
339-
},
340-
{
341-
"CohortLabel": "rsv_75to79_2024",
342-
"CohortGroup": "rsv_age_catchup",
343-
"PositiveDescription": "turned 80 between 2nd September 2024 and 31st August 2025",
344-
"NegativeDescription": "did not turn 80 between 2nd September 2024 and 31st August 2025",
345-
"Priority": 10
346-
},
347-
{
348-
"CohortLabel": "elid_all_people",
349-
"CohortGroup": "elid_all_people",
350-
"PositiveDescription": "",
351-
"NegativeDescription": "",
352-
"Priority": 20
353-
},
354-
{
355-
"CohortLabel": "no_group_description",
356-
"CohortGroup": "",
357-
"PositiveDescription": "",
358-
"NegativeDescription": "",
359-
"Priority": 30
360-
}
361-
],
362-
"IterationRules":
363-
[
364-
{
365-
"Type": "F",
366-
"Name": "Assure only already vaccinated taken from magic cohort",
367-
"Description": "Exclude anyone who has NOT been given a dose of RSV Vaccination from the magic cohort",
368-
"Operator": "is_empty",
369-
"Comparator": "",
370-
"AttributeTarget": "RSV",
371-
"AttributeLevel": "TARGET",
372-
"AttributeName": "LAST_SUCCESSFUL_DATE",
373-
"CohortLabel": "elid_all_people",
374-
"Priority": 100
375-
},
376-
{
377-
"Type": "F",
378-
"Name": "Under Age - Under 75 Years on day of execution",
379-
"Description": "Ensure anyone who has a PDS date of birth which determines their age to be less than 75 years is filtered out.",
380-
"Priority": 120,
381-
"AttributeLevel": "PERSON",
382-
"AttributeName": "DATE_OF_BIRTH",
383-
"Operator": "Y>",
384-
"Comparator": "-75",
385-
"CohortLabel": "rsv_75to79_2024"
386-
},
387-
{
388-
"Type": "F",
389-
"Name": "Under Age - Under 75 Years on day of execution",
390-
"Description": "Ensure anyone who has a PDS date of birth which determines their age to be less than 75 years is filtered out.",
391-
"Priority": 125,
392-
"AttributeLevel": "PERSON",
393-
"AttributeName": "DATE_OF_BIRTH",
394-
"Operator": "Y>",
395-
"Comparator": "-75",
396-
"CohortLabel": "rsv_75_rolling"
397-
},
398-
{
399-
"Type": "F",
400-
"Name": "Exclude Too OLD",
401-
"Description": "Exclude anyone over 80",
402-
"Priority": 130,
403-
"AttributeLevel": "PERSON",
404-
"AttributeName": "DATE_OF_BIRTH",
405-
"Operator": "<",
406-
"Comparator": "-80"
407-
},
408-
{
409-
"Type": "S",
410-
"Name": "AlreadyVaccinated",
411-
"Description": "##You've had your RSV vaccination\nWe believe you had your vaccination on <<LAST_SUCCESSFUL_DATE>>.",
412-
"Priority": 550,
413-
"AttributeLevel": "TARGET",
414-
"AttributeTarget": "RSV",
415-
"AttributeName": "LAST_SUCCESSFUL_DATE",
416-
"Operator": "Y>=",
417-
"Comparator": "-25",
418-
"RuleStop": "Y"
419-
},
420-
{
421-
"Type": "S",
422-
"Name": "NotAvailable",
423-
"Description": "NotAvailable|Vaccinations are not currently available.",
424-
"Priority": 510,
425-
"AttributeLevel": "PERSON",
426-
"AttributeName": "ICB",
427-
"Operator": "=",
428-
"Comparator": "SUPPRESSED_ICB"
429-
},
430-
{
431-
"Type": "S",
432-
"Name": "NotYetDue",
433-
"Description": "NotYetDue|Your next dose is not yet due.",
434-
"Priority": 520,
435-
"AttributeTarget": "RSV",
436-
"AttributeLevel": "TARGET",
437-
"AttributeName": "LAST_SUCCESSFUL_DATE",
438-
"Operator": "=",
439-
"Comparator": "20250326",
440-
"RuleStop": "Y"
441-
},
442-
{
443-
"Type": "S",
444-
"Name": "TooClose",
445-
"Description": "TooClose|Your previous vaccination was less than 91 days ago.",
446-
"Priority": 530,
447-
"AttributeTarget": "RSV",
448-
"AttributeLevel": "TARGET",
449-
"AttributeName": "LAST_SUCCESSFUL_DATE",
450-
"Operator": "=",
451-
"Comparator": "20250327",
452-
"RuleStop": "Y"
453-
},
454-
{
455-
"Type": "S",
456-
"Name": "OtherSetting",
457-
"Description": "OtherSetting|## Getting the vaccine\n\nOur record show you're living in a setting where care is provided.\n\nIf you think you should have the RSV vaccine, speak to a member of staff where you live.",
458-
"Priority": 540,
459-
"AttributeLevel": "PERSON",
460-
"AttributeName": "CARE_HOME_FLAG",
461-
"Operator": "=",
462-
"Comparator": "Y"
463-
},
464-
{
465-
"Type": "R",
466-
"Name": "Actionable Not Vaccinated",
467-
"Description": "Book An Appointment",
468-
"Priority": 1010,
469-
"Operator": "is_empty",
470-
"Comparator": "",
471-
"AttributeTarget": "RSV",
472-
"AttributeLevel": "TARGET",
473-
"AttributeName": "LAST_SUCCESSFUL_DATE",
474-
"CommsRouting": "BOOK_NBS"
475-
},
476-
{
477-
"Type": "R",
478-
"Name": "Actionable Not Vaccinated",
479-
"Description": "Book An Appointment",
480-
"Priority": 1010,
481-
"Operator": "=",
482-
"Comparator": "LS2",
483-
"AttributeLevel": "PERSON",
484-
"AttributeName": "POSTCODE_SECTOR",
485-
"CommsRouting": "BOOK_NBS"
486-
},
487-
{
488-
"Type": "R",
489-
"Name": "Actionable Future Booked Appointment",
490-
"Description": "Actionable Future Booked Appointment",
491-
"Priority": 1020,
492-
"Operator": ">=",
493-
"Comparator": "0",
494-
"AttributeTarget": "RSV",
495-
"AttributeLevel": "TARGET",
496-
"AttributeName": "BOOKED_APPOINTMENT_DATE",
497-
"CommsRouting": "AMEND_NBS"
498-
},
499-
{
500-
"Type": "R",
501-
"Name": "Actionable Future Booked Appointment",
502-
"Description": "Actionable Future Booked Appointment",
503-
"Priority": 1020,
504-
"Operator": "=",
505-
"Comparator": "NBS",
506-
"AttributeTarget": "RSV",
507-
"AttributeLevel": "TARGET",
508-
"AttributeName": "BOOKED_APPOINTMENT_PROVIDER",
509-
"CommsRouting": "AMEND_NBS"
510-
},
511-
{
512-
"Type": "R",
513-
"Name": "Actionable Future Booked Appointment",
514-
"Description": "Actionable Future Booked Appointment",
515-
"Priority": 1030,
516-
"Operator": ">=",
517-
"Comparator": "0",
518-
"AttributeTarget": "RSV",
519-
"AttributeLevel": "TARGET",
520-
"AttributeName": "BOOKED_APPOINTMENT_DATE",
521-
"CommsRouting": "MANAGE_LOCAL"
522-
},
523-
{
524-
"Type": "R",
525-
"Name": "Actionable Future Booked Appointment",
526-
"Description": "Actionable Future Booked Appointment",
527-
"Priority": 1030,
528-
"Operator": "!=",
529-
"Comparator": "NBS",
530-
"AttributeTarget": "RSV",
531-
"AttributeLevel": "TARGET",
532-
"AttributeName": "BOOKED_APPOINTMENT_PROVIDER",
533-
"CommsRouting": "MANAGE_LOCAL"
534-
},
535-
{
536-
"Type": "X",
537-
"Name": "Test X Rule for not eligible",
538-
"Description": "Test X Rule Desc",
539-
"Priority": 20,
540-
"AttributeLevel": "PERSON",
541-
"AttributeName": "DATE_OF_BIRTH",
542-
"Operator": ">",
543-
"Comparator": "19000101",
544-
"CommsRouting": "XRULEID1|INTERNALTESCO"
545-
},
546-
{
547-
"Type": "Y",
548-
"Name": "Test Y Rule for not actionable",
549-
"Description": "Test Y Rule Desc",
550-
"Priority": 20,
551-
"AttributeLevel": "PERSON",
552-
"AttributeName": "DATE_OF_BIRTH",
553-
"Operator": ">",
554-
"Comparator": "19000101",
555-
"CommsRouting": "YRULEID1|INTERNALTESCO"
556-
}
557-
],
558-
"ActionsMapper":
559-
{
560-
"BOOK_NBS":
561-
{
562-
"ExternalRoutingCode": "BookNBS",
563-
"ActionDescription": "",
564-
"ActionType": "ButtonWithAuthLink",
565-
"UrlLink": "http://www.nhs.uk/book-rsv",
566-
"UrlLabel": "Continue to booking"
567-
},
568-
"AMEND_NBS":
569-
{
570-
"ExternalRoutingCode": "AmendNBS",
571-
"ActionDescription": "##You have an RSV vaccination appointment\nYou can view, change or cancel your appointment below.",
572-
"ActionType": "ButtonWithAuthLink",
573-
"UrlLink": "http://www.nhs.uk/book-rsv",
574-
"UrlLabel": "Manage your appointment"
575-
},
576-
"CONTACT_GP":
577-
{
578-
"ExternalRoutingCode": "ContactGP",
579-
"ActionDescription": "Contact your GP",
580-
"ActionType": "InfoText"
581-
},
582-
"BOOK_LOCAL":
583-
{
584-
"ExternalRoutingCode": "BookLocal",
585-
"ActionDescription": "##Getting the vaccine\nYou can get an RSV vaccination at your GP surgery.\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.",
586-
"ActionType": "InfoText"
587-
},
588-
"MANAGE_LOCAL":
589-
{
590-
"ExternalRoutingCode": "ManageLocal",
591-
"ActionDescription": "##You have an RSV vaccination appointment\nContact your healthcare provider to change or cancel your appointment.",
592-
"ActionType": "CardWithText"
593-
},
594-
"CHECK_CORRECT":
595-
{
596-
"ExternalRoutingCode": "CheckCorrect",
597-
"ActionDescription": "##If you think this is incorrect\\nIf you have not had this vaccination and you think you should, speak to your healthcare professional.",
598-
"ActionType": "InfoText"
599-
},
600-
"XRULEID1":
601-
{
602-
"ExternalRoutingCode": "FINDWALKIN",
603-
"ActionDescription": "Find walkin description",
604-
"ActionType": "button"
605-
},
606-
"YRULEID1":
607-
{
608-
"ExternalRoutingCode": "FINDWALKIN",
609-
"ActionDescription": "Find walkin description",
610-
"ActionType": "button"
611-
}
612-
}
613317
}
614318
]
615319
}

src/rules_validation_api/validators/campaign_config_validator.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
from typing import List
22

3-
from pydantic import field_validator
3+
from pydantic import field_validator, Field
44

55
from eligibility_signposting_api.model.campaign_config import CampaignConfig, Iteration
66
from rules_validation_api.validators.iteration_validator import IterationValidation
77

88

99
class CampaignConfigValidation(CampaignConfig):
10+
iterations: List[IterationValidation] = Field(..., min_length=1, alias="Iterations")
1011

1112
@field_validator("id")
1213
def validate_name(cls, value: str) -> str:
@@ -21,5 +22,3 @@ def validate_type(cls, value: str) -> str:
2122
raise ValueError(f"type must be one of {allowed_values}")
2223
return value
2324

24-
iterations: List[IterationValidation]
25-
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
1-
from pydantic import field_validator
1+
from pydantic import field_validator, BaseModel
22

33
from eligibility_signposting_api.model.campaign_config import Iteration
44

5-
65
class IterationValidation(Iteration):
6+
7+
@field_validator("id")
8+
@classmethod
9+
def validate_name(cls, value: str) -> str:
10+
if not value.strip():
11+
raise ValueError("ID must not be empty")
12+
return value
13+
714
@field_validator("id")
15+
@classmethod
816
def validate_name(cls, value: str) -> str:
917
if not value.strip():
1018
raise ValueError("ID must not be empty")
1119
return value
20+
21+

0 commit comments

Comments
 (0)