@@ -273,26 +273,27 @@ def get_case_review(self, case_config_id): # pragma: no cover
273273 1) Load saved DisplayConfig for this case_config_id + user_email.
274274 2) Build full unpruned case_details tree.
275275 3) Prune under “BACKGROUND” according to CSV path_config.
276- 4) If CSV included a “ Colorectal Cancer Score” entry , use that value
277- directly under “AI CRC Risk Score (<6: Low; 6-11: Medium; >11: High)”.
278- 5) Otherwise, if CSV toggled CRC risk assessments, look first for a
279- “Colorectal Cancer Score” observation in the DB; if none, fall
280- back to the old “Adjusted CRC Risk” observation logic. If still
281- nothing, emit “N/A” .
276+ 4) If CSV included a literal Colorectal Cancer Score leaf , use that directly.
277+ 5) Else if CSV toggled CRC risk assessments, look for an observation row:
278+ a) First, any value_as_string starting with "Colorectal Cancer Score"
279+ b) Then, any "Adjusted CRC Risk" row (renaming it)
280+ c) If neither found, emit "N/A"
281+ 6) If CSV had no RISK ASSESSMENT entries at all, do not emit any CRC score node .
282282 """
283- # load configuration & verify access
283+ # --- 1) Load configuration & verify access ---
284284 configuration = self .configuration_repository .get_configuration_by_id (case_config_id )
285285 current_user = get_user_email_from_jwt ()
286286 if not configuration or configuration .user_email != current_user :
287287 raise BusinessException (BusinessExceptionEnum .NoAccessToCaseReview )
288288
289- # raw , unpruned
289+ # --- 2) Raw , unpruned case tree ---
290290 case_details = self .get_case_detail (configuration .case_id )
291291
292- # index CSV path_config entries
292+ # --- 3) Index CSV path_config entries ---
293293 raw_path_cfg = configuration .path_config or []
294294 parent_to_entries : dict [str , list [dict ]] = defaultdict (list )
295295
296+ # Track whether CSV provided an explicit literal score or just toggled the section
296297 csv_crc_score_leaf : str | None = None
297298 old_crc_toggle = False
298299
@@ -303,40 +304,43 @@ def get_case_review(self, case_config_id): # pragma: no cover
303304 continue
304305
305306 segments = path_str .split ("." )
307+ # We need at least a parent and a leaf
306308 if len (segments ) < 2 :
307309 continue
308310
309311 parent_key = "." .join (segments [:- 1 ])
310312 leaf_text = segments [- 1 ]
311313
312- # CSV‐ provided score override?
314+ # CSV- provided literal score override?
313315 if path_str .startswith ("RISK ASSESSMENT.Colorectal Cancer Score" ):
314316 csv_crc_score_leaf = leaf_text
315317
316- # old‐ style toggle
318+ # Old- style toggle of the entire CRC section?
317319 if path_str == "RISK ASSESSMENT.CRC risk assessments" :
318320 old_crc_toggle = True
319321
320322 parent_to_entries [parent_key ].append ({"leaf" : leaf_text , "style" : style })
321323
322- # prune under BACKGROUND
324+ # --- 4) Prune under BACKGROUND according to path_config ---
323325 important_infos : list [dict ] = []
324326 for top in case_details :
325327 if top .key != "BACKGROUND" :
326328 continue
327329 for child in top .values :
328330 if child .key == "Patient Demographics" :
331+ # always keep demographics
329332 continue
330-
331333 pk = f"BACKGROUND.{ child .key } "
332334 if pk not in parent_to_entries :
335+ # no CSV entries for this category ⇒ drop it entirely
333336 child .values = []
334337 continue
335-
336338 entries = parent_to_entries [pk ]
339+ # only keep those leaves the CSV listed
337340 keep = {e ["leaf" ] for e in entries }
338341 child .values = [v for v in child .values if v in keep ]
339342
343+ # merge style directives (collapse, highlight, top)
340344 merged : dict = {}
341345 for e in entries :
342346 s = e ["style" ]
@@ -348,30 +352,32 @@ def get_case_review(self, case_config_id): # pragma: no cover
348352 merged ["top" ] = max (merged .get ("top" , - 1 ), s ["top" ])
349353
350354 child .style = merged
351- if "top" in merged :
355+ # collect any "top"-weighted nodes for separate display
356+ if merged .get ("top" ) is not None :
352357 important_infos .append ({
353358 "key" : child .key ,
354359 "values" : child .values ,
355360 "weight" : merged ["top" ],
356361 })
357362
358- # sort & wrap
363+ # sort by weight and wrap into TreeNodes
359364 important_infos .sort (key = itemgetter ("weight" ))
360365 sorted_important = [TreeNode (e ["key" ], e ["values" ]) for e in important_infos ]
361366
362- # label we use in the UI
367+ # --- 5) Handle AI CRC Risk Score section only if CSV referenced it ---
363368 ai_label = "AI CRC Risk Score (<6: Low; 6-11: Medium; >11: High)"
364369
365370 if csv_crc_score_leaf :
371+ # CSV gave us the exact leaf text to show
366372 sorted_important .append (TreeNode (ai_label , [csv_crc_score_leaf ]))
367373
368- # fallback branch
369374 elif old_crc_toggle :
375+ # CSV toggled the section but did not supply a literal score; fetch from DB
370376 crc_obs = self .observation_repository .get_observations_by_concept (
371377 configuration .case_id , [45614722 ]
372378 )
373379
374- # (i) is there a literal Colorectal Cancer Score: X row?
380+ # (a) look first for any literal " Colorectal Cancer Score: X"
375381 csv_obs = next (
376382 (
377383 o .value_as_string
@@ -383,24 +389,24 @@ def get_case_review(self, case_config_id): # pragma: no cover
383389 if csv_obs :
384390 sorted_important .append (TreeNode (ai_label , [csv_obs ]))
385391 else :
386- # (ii) fall back to Adjusted CRC Risk
392+ # (b) fallback to any " Adjusted CRC Risk" row
387393 for obs in crc_obs :
388394 txt = obs .value_as_string or ""
389395 if txt .startswith ("Adjusted CRC Risk" ):
396+ # rename to match "AI-Predicted CRC Risk Score"
390397 new_txt = txt .replace (
391398 "Adjusted CRC Risk" ,
392399 "AI-Predicted CRC Risk Score"
393400 )
394401 sorted_important .append (TreeNode (ai_label , [new_txt ]))
395402 break
396403 else :
397- # (iii) still nothing? emit N/A
404+ # (c) CSV toggled but no score found ⇒ explicitly show N/A
398405 sorted_important .append (TreeNode (ai_label , ["N/A" ]))
399406
400- # if neither CSV nor old toggle, emit N/A
401- else :
402- sorted_important .append (TreeNode (ai_label , ["N/A" ]))
407+ # 6) If neither csv_crc_score_leaf nor old_crc_toggle, we do not append any CRC score node.
403408
409+ # --- 7) Return the assembled Case object ---
404410 return Case (
405411 self .person .person_source_value ,
406412 str (configuration .case_id ),
0 commit comments