@@ -1042,4 +1042,149 @@ async def link_slack_user(self, slack_id: str, email: str) -> Optional[int]:
10421042 print (f"Failed to link Slack user: { e } " )
10431043 return None
10441044
1045+ # --- MedHack Game State ---
1046+
1047+ async def medhack_get_current_case (self ) -> Optional [dict ]:
1048+ """Get the currently active MedHack case."""
1049+ try :
1050+ async with httpx .AsyncClient () as client :
1051+ response = await client .get (
1052+ f"{ self .base_url } /api/v1/medhack/cases/current/" ,
1053+ headers = self .headers ,
1054+ timeout = 10.0
1055+ )
1056+ if response .status_code == 404 :
1057+ return None
1058+ response .raise_for_status ()
1059+ return response .json ()
1060+ except Exception as e :
1061+ print (f"⚠️ MedHack get current case error: { e } " )
1062+ return None
1063+
1064+ async def medhack_start_case (self , case_id : int , admin_slack_id : str ) -> Optional [dict ]:
1065+ """Start a new MedHack case (admin only). Closes any active case."""
1066+ try :
1067+ async with httpx .AsyncClient () as client :
1068+ response = await client .post (
1069+ f"{ self .base_url } /api/v1/medhack/cases/start/" ,
1070+ json = {"case_id" : case_id , "admin_slack_id" : admin_slack_id },
1071+ headers = self .admin_headers ,
1072+ timeout = 10.0
1073+ )
1074+ response .raise_for_status ()
1075+ return response .json ()
1076+ except httpx .HTTPStatusError as e :
1077+ if e .response .status_code == 403 :
1078+ print (f"⚠️ MedHack start case: not authorized" )
1079+ return None
1080+ raise
1081+ except Exception as e :
1082+ print (f"⚠️ MedHack start case error: { e } " )
1083+ return None
1084+
1085+ async def medhack_get_user_status (self , slack_user_id : str ) -> Optional [dict ]:
1086+ """Get a user's status for the active MedHack case."""
1087+ try :
1088+ async with httpx .AsyncClient () as client :
1089+ response = await client .get (
1090+ f"{ self .base_url } /api/v1/medhack/cases/active/user/{ slack_user_id } /" ,
1091+ headers = self .headers ,
1092+ timeout = 10.0
1093+ )
1094+ if response .status_code == 404 :
1095+ return None
1096+ response .raise_for_status ()
1097+ return response .json ()
1098+ except Exception as e :
1099+ print (f"⚠️ MedHack get user status error: { e } " )
1100+ return None
1101+
1102+ async def medhack_set_pending_guess (self , case_id : int , slack_user_id : str , guess : str ) -> Optional [dict ]:
1103+ """Store a pending guess awaiting user confirmation."""
1104+ try :
1105+ async with httpx .AsyncClient () as client :
1106+ response = await client .post (
1107+ f"{ self .base_url } /api/v1/medhack/guesses/pending/" ,
1108+ json = {"case_id" : case_id , "slack_user_id" : slack_user_id , "guess" : guess },
1109+ headers = self .headers ,
1110+ timeout = 10.0
1111+ )
1112+ response .raise_for_status ()
1113+ return response .json ()
1114+ except Exception as e :
1115+ print (f"⚠️ MedHack set pending guess error: { e } " )
1116+ return None
1117+
1118+ async def medhack_clear_pending_guess (self , case_id : int , slack_user_id : str ) -> bool :
1119+ """Clear a user's pending guess."""
1120+ try :
1121+ async with httpx .AsyncClient () as client :
1122+ response = await client .request (
1123+ "DELETE" ,
1124+ f"{ self .base_url } /api/v1/medhack/guesses/pending/" ,
1125+ json = {"case_id" : case_id , "slack_user_id" : slack_user_id },
1126+ headers = self .headers ,
1127+ timeout = 10.0
1128+ )
1129+ return response .status_code == 204
1130+ except Exception as e :
1131+ print (f"⚠️ MedHack clear pending guess error: { e } " )
1132+ return False
1133+
1134+ async def medhack_submit_guess (
1135+ self , case_id : int , slack_user_id : str , guess : str , correct : bool
1136+ ) -> Optional [dict ]:
1137+ """Submit a confirmed guess."""
1138+ try :
1139+ async with httpx .AsyncClient () as client :
1140+ response = await client .post (
1141+ f"{ self .base_url } /api/v1/medhack/guesses/submit/" ,
1142+ json = {
1143+ "case_id" : case_id ,
1144+ "slack_user_id" : slack_user_id ,
1145+ "guess" : guess ,
1146+ "correct" : correct ,
1147+ },
1148+ headers = self .headers ,
1149+ timeout = 10.0
1150+ )
1151+ response .raise_for_status ()
1152+ return response .json ()
1153+ except Exception as e :
1154+ print (f"⚠️ MedHack submit guess error: { e } " )
1155+ return None
1156+
1157+ async def medhack_record_winner (
1158+ self , case_id : int , slack_user_id : str , is_first_solver : bool
1159+ ) -> Optional [dict ]:
1160+ """Record a winner for a MedHack case."""
1161+ try :
1162+ async with httpx .AsyncClient () as client :
1163+ response = await client .post (
1164+ f"{ self .base_url } /api/v1/medhack/cases/{ case_id } /winners/" ,
1165+ json = {"slack_user_id" : slack_user_id , "is_first_solver" : is_first_solver },
1166+ headers = self .headers ,
1167+ timeout = 10.0
1168+ )
1169+ response .raise_for_status ()
1170+ return response .json ()
1171+ except Exception as e :
1172+ print (f"⚠️ MedHack record winner error: { e } " )
1173+ return None
1174+
1175+ async def medhack_get_case_history (self ) -> list :
1176+ """Get history of all played MedHack cases."""
1177+ try :
1178+ async with httpx .AsyncClient () as client :
1179+ response = await client .get (
1180+ f"{ self .base_url } /api/v1/medhack/cases/history/" ,
1181+ headers = self .headers ,
1182+ timeout = 10.0
1183+ )
1184+ response .raise_for_status ()
1185+ return response .json ().get ("cases" , [])
1186+ except Exception as e :
1187+ print (f"⚠️ MedHack get case history error: { e } " )
1188+ return []
1189+
10451190 # End of MLAIBackendClient
0 commit comments