11# mock_selection_builder.py — Development-only testing harness for criteria logic
22import sys
33import os
4+ from typing import Optional
45
56sys .path .insert (0 , os .path .abspath (os .path .join (os .path .dirname (__file__ ), "../.." )))
67from classes .selection_builder_exception import SelectionBuilderException
78from classes .subject_selection_criteria_key import SubjectSelectionCriteriaKey
89
910
1011# Add helper class stubs below
11- class ScreeningReferralType :
12+ class Subject :
13+ def __init__ (self , lynch_due_date_change_reason_id ):
14+ self .lynch_due_date_change_reason_id = lynch_due_date_change_reason_id
15+
16+
17+ class LynchIncidentEpisodeType :
1218 """
13- Maps screening referral descriptions to valid value IDs .
19+ Maps symbolic criteria values for Lynch incident episode linkage .
1420 """
1521
16- _label_to_id = {
17- "gp" : 9701 ,
18- "self referral" : 9702 ,
19- "hospital" : 9703 ,
20- # Extend as needed
21- }
22+ NULL = "null"
23+ NOT_NULL = "not_null"
24+ LATEST_EPISODE = "latest_episode"
25+ EARLIER_EPISODE = "earlier_episode"
26+
27+ _symbolics = { NULL , NOT_NULL , LATEST_EPISODE , EARLIER_EPISODE }
2228
2329 @classmethod
24- def get_id (cls , description : str ) -> int :
30+ def from_description (cls , description : str ) -> str :
2531 key = description .strip ().lower ()
26- if key not in cls ._label_to_id :
27- raise ValueError (f"Unknown screening referral type: '{ description } '" )
28- return cls ._label_to_id [key ]
32+ if key not in cls ._symbolics :
33+ raise ValueError (
34+ f"Unknown Lynch incident episode criteria: '{ description } '"
35+ )
36+ return key
2937
3038
3139class MockSelectionBuilder :
@@ -71,6 +79,10 @@ def _add_join_to_latest_episode(self) -> None:
7179 """
7280 self .sql_from .append ("-- JOIN to latest episode placeholder" )
7381
82+ def _force_not_modifier_is_invalid (self ):
83+ # Placeholder for rule enforcement. No-op in mock builder.
84+ pass
85+
7486 def _dataset_source_for_criteria_key (self ) -> dict :
7587 """
7688 Maps criteria key to dataset table and alias.
@@ -94,19 +106,26 @@ def _add_join_to_surveillance_review(self):
94106 # Replace this with the one you want to test,
95107 # then use utils/oracle/test_subject_criteria_dev.py to run your scenarios
96108
97- def _add_criteria_screening_referral_type (self ) -> None :
109+ def _add_criteria_lynch_incident_episode (self ) -> None :
98110 """
99- Filters based on screening referral type ID or null presence .
111+ Filters based on linkage to a Lynch incident episode .
100112 """
101113 try :
102- column = "xt.screening_referral_type_id"
103- value = self .criteria_value .strip ().lower ()
114+ self ._add_join_to_latest_episode ()
115+ column = "ss.lynch_incident_subject_epis_id"
116+ value = LynchIncidentEpisodeType .from_description (self .criteria_value )
104117
105- if value == "null" :
118+ if value == LynchIncidentEpisodeType . NULL :
106119 self .sql_where .append (f"AND { column } IS NULL" )
107- else :
108- type_id = ScreeningReferralType .get_id (self .criteria_value )
109- self .sql_where .append (f"AND { column } { self .criteria_comparator } { type_id } " )
120+
121+ elif value == LynchIncidentEpisodeType .NOT_NULL :
122+ self .sql_where .append (f"AND { column } IS NOT NULL" )
123+
124+ elif value == LynchIncidentEpisodeType .LATEST_EPISODE :
125+ self .sql_where .append (f"AND { column } = ep.subject_epis_id" )
126+
127+ elif value == LynchIncidentEpisodeType .EARLIER_EPISODE :
128+ self .sql_where .append (f"AND { column } < ep.subject_epis_id" )
110129
111130 except Exception :
112131 raise SelectionBuilderException (self .criteria_key_name , self .criteria_value )
0 commit comments