medicafe 0.250812.4__py3-none-any.whl → 0.250812.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
MediBot/MediBot.bat CHANGED
@@ -2,11 +2,31 @@
2
2
  @echo off
3
3
  setlocal enabledelayedexpansion
4
4
 
5
- :: Debug mode selection
5
+ :: Clear screen before launcher header
6
+ cls
7
+
8
+ :: Launcher header
6
9
  echo ========================================
7
10
  echo MediCafe Launcher
8
11
  echo ========================================
9
12
  echo.
13
+
14
+ :: Hidden debug access: 1-second Enter-to-open gate; otherwise start normal mode
15
+ echo Press Enter within 1 second to open Debug Options... (otherwise starting Normal Mode)
16
+ rem Prefer timeout for key-break; fall back to ping if unavailable
17
+ where timeout >nul 2>&1
18
+ if errorlevel 1 (
19
+ rem Fallback: simple 1-second delay (no key detection on XP fallback)
20
+ ping -n 2 127.0.0.1 >nul
21
+ goto start_normal_mode
22
+ ) else (
23
+ timeout /t 1 >nul 2>nul
24
+ if errorlevel 1 goto show_debug_menu
25
+ goto start_normal_mode
26
+ )
27
+
28
+ :show_debug_menu
29
+ echo.
10
30
  echo Choose your mode:
11
31
  echo 1. Normal Mode - Production
12
32
  echo 2. Debug Mode - Full diagnostics (Interactive)
@@ -127,6 +147,8 @@ set "claims_status_script=..\MediLink\MediLink_ClaimStatus.py"
127
147
  set "deductible_script=..\MediLink\MediLink_Deductible.py"
128
148
  set "package_version="
129
149
  set PYTHONWARNINGS=ignore
150
+ set "PRES_WARN_UPDATE_SCRIPT=0"
151
+ set "PRES_WARN_NO_INTERNET=0"
130
152
 
131
153
  :: Check if Python is installed
132
154
  python --version >nul 2>&1
@@ -186,6 +208,7 @@ if defined package_version (
186
208
  ping -n 1 google.com >nul 2>&1
187
209
  if errorlevel 1 (
188
210
  set "internet_available=0"
211
+ set "PRES_WARN_NO_INTERNET=1"
189
212
  ) else (
190
213
  set "internet_available=1"
191
214
  echo Internet connection detected.
@@ -322,6 +345,7 @@ if exist "%upgrade_medicafe_local%" (
322
345
  ping -n 2 127.0.0.1 >nul
323
346
  ) else (
324
347
  echo update_medicafe.py not detected in any known location.
348
+ set "PRES_WARN_UPDATE_SCRIPT=1"
325
349
  echo.
326
350
  echo Checked locations:
327
351
  echo - Site-packages: C:\Python34\Lib\site-packages\MediBot\update_medicafe.py
@@ -351,6 +375,16 @@ echo .//* Welcome to MediCafe *\\.
351
375
  echo --------------------------------------------------------------
352
376
  echo.
353
377
 
378
+ :: Preserve important warnings/errors from boot sequence
379
+ if "%PRES_WARN_UPDATE_SCRIPT%"=="1" (
380
+ echo [WARNING] Update helper script not detected during startup. Update features may be limited.
381
+ echo.
382
+ )
383
+ if "%PRES_WARN_NO_INTERNET%"=="1" (
384
+ echo [WARNING] No internet connectivity detected during startup.
385
+ echo.
386
+ )
387
+
354
388
  if "!internet_available!"=="0" (
355
389
  echo NOTE: No internet detected. Options 1-5 require internet.
356
390
  echo.
@@ -371,8 +405,6 @@ echo 6. Run MediBot
371
405
  echo.
372
406
  echo 7. Troubleshooting
373
407
  echo.
374
- echo 9. Toggle Performance Logging (session)
375
- echo.
376
408
  echo 8. Exit
377
409
  echo.
378
410
  set /p choice=Enter your choice:
@@ -386,7 +418,6 @@ if "!choice!"=="4" goto united_claims_status
386
418
  if "!choice!"=="3" goto medilink_flow
387
419
  if "!choice!"=="2" goto download_emails
388
420
  if "!choice!"=="1" goto check_updates
389
- if "!choice!"=="9" goto toggle_perf_logging
390
421
  if "!choice!"=="0" goto end_script
391
422
 
392
423
  echo Invalid choice. Please try again.
@@ -538,7 +569,7 @@ if not exist "%_UPD_RUNNER%" (
538
569
  echo.
539
570
  echo Launching updater and closing this window...
540
571
  start "MediCafe Update" "%_UPD_RUNNER%"
541
- exit /b 0
572
+ exit 0
542
573
 
543
574
  :: Download Carol's Emails
544
575
  :download_emails
@@ -602,7 +633,7 @@ if /I "%MEDICAFE_PERFORMANCE_LOGGING%"=="1" (
602
633
  echo.
603
634
  echo Note: This affects current session only. To persist, set in config.json.
604
635
  pause
605
- goto main_menu
636
+ goto troubleshooting_menu
606
637
 
607
638
  :: United Claims Status
608
639
  :united_claims_status
@@ -681,14 +712,16 @@ echo Troubleshooting Options:
681
712
  echo.
682
713
  echo 1. Open Latest Log File
683
714
  echo 2. Clear Python Cache
684
- echo 3. Forced MediCafe version rollback - no dependencies
685
- echo 4. Back to Main Menu
715
+ echo 3. Toggle Performance Logging ^(session^)
716
+ echo 4. Forced MediCafe version rollback
717
+ echo 5. Back to Main Menu
686
718
  echo.
687
719
  set /p tchoice=Enter your choice:
688
720
  if "%tchoice%"=="1" goto open_latest_log
689
721
  if "%tchoice%"=="2" goto clear_cache_menu
690
- if "%tchoice%"=="3" goto forced_version_rollback
691
- if "%tchoice%"=="4" goto main_menu
722
+ if "%tchoice%"=="3" goto toggle_perf_logging
723
+ if "%tchoice%"=="4" goto forced_version_rollback
724
+ if "%tchoice%"=="5" goto main_menu
692
725
  echo Invalid choice. Please try again.
693
726
  pause
694
727
  goto troubleshooting_menu
@@ -709,7 +742,7 @@ goto troubleshooting_menu
709
742
  :: End Script
710
743
  :end_script
711
744
  echo Exiting MediBot
712
- exit /b 0
745
+ exit 0
713
746
 
714
747
  :: Full Debug Mode moved to external script full_debug_suite.bat
715
748
 
MediBot/MediBot.py CHANGED
@@ -73,6 +73,45 @@ except ImportError as e:
73
73
  # Make API client optional - don't log warning for now
74
74
  pass
75
75
 
76
+ # Buffer for startup warnings/errors so we can re-display them after clearing the console
77
+ STARTUP_NOTICES = []
78
+
79
+ def record_startup_warning(message):
80
+ """Record a startup warning, log it, and print it immediately.
81
+ Stored warnings will be reprinted after the screen is cleared.
82
+ """
83
+ try:
84
+ STARTUP_NOTICES.append(('WARNING', message))
85
+ except Exception:
86
+ pass
87
+ try:
88
+ if MediLink_ConfigLoader:
89
+ MediLink_ConfigLoader.log(message, level="WARNING")
90
+ except Exception:
91
+ pass
92
+ try:
93
+ print(message)
94
+ except Exception:
95
+ pass
96
+
97
+ def record_startup_error(message):
98
+ """Record a startup error, log it, and print it immediately.
99
+ Stored errors will be reprinted after the screen is cleared.
100
+ """
101
+ try:
102
+ STARTUP_NOTICES.append(('ERROR', message))
103
+ except Exception:
104
+ pass
105
+ try:
106
+ if MediLink_ConfigLoader:
107
+ MediLink_ConfigLoader.log(message, level="ERROR")
108
+ except Exception:
109
+ pass
110
+ try:
111
+ print(message)
112
+ except Exception:
113
+ pass
114
+
76
115
  def identify_field(header, field_mapping):
77
116
  for medisoft_field, patterns in field_mapping.items():
78
117
  for pattern in patterns:
@@ -448,12 +487,10 @@ class ExecutionState:
448
487
  MediLink_ConfigLoader.log("Crosswalk update completed successfully.", level="INFO")
449
488
  print("Crosswalk update completed successfully.")
450
489
  else:
451
- MediLink_ConfigLoader.log("Crosswalk update failed.", level="ERROR")
452
- print("Crosswalk update failed.")
490
+ record_startup_error("Crosswalk update failed.")
453
491
 
454
492
  except Exception as e:
455
- MediLink_ConfigLoader.log("MediBot: Failed to load or update configuration: {}".format(e), level="ERROR")
456
- print("MediBot: Failed to load or update configuration: {}".format(e))
493
+ record_startup_error("MediBot: Failed to load or update configuration: {}".format(e))
457
494
  raise # Re-throwing the exception or using a more sophisticated error handling mechanism might be needed
458
495
  # Handle the exception somehow (e.g., retry, halt, log)??
459
496
 
@@ -544,9 +581,18 @@ if __name__ == "__main__":
544
581
  MediLink_ConfigLoader.log("Load Complete event triggered. Clearing console. Displaying Menu...", level="INFO")
545
582
  # Windows XP console buffer fix: Use cls with echo to reset buffer state
546
583
  # Add a debug switch to optionally skip clearing the console for debugging purposes
547
- CLEAR_CONSOLE_ON_LOAD = False # Set to False to keep previous output visible for debugging
584
+ CLEAR_CONSOLE_ON_LOAD = True # Clear screen before menu for cleaner UI
548
585
  if CLEAR_CONSOLE_ON_LOAD:
549
586
  _ = os.system('cls && echo.')
587
+ # Re-display critical startup notices so the user still sees them
588
+ if STARTUP_NOTICES:
589
+ print("Important notices from startup:")
590
+ for lvl, msg in STARTUP_NOTICES:
591
+ try:
592
+ print("[{}] {}".format(lvl, msg))
593
+ except Exception:
594
+ print(msg)
595
+ print("-" * 60)
550
596
 
551
597
  proceed, selected_patient_ids, selected_indices, fixed_values = user_interaction(csv_data, interaction_mode, error_message, reverse_mapping)
552
598
 
@@ -556,7 +602,7 @@ if __name__ == "__main__":
556
602
 
557
603
  # Check if MAPAT_MED_PATH is missing or invalid
558
604
  if (not _ac()) or (not _ac().get_mapat_med_path()) or (not os.path.exists(_ac().get_mapat_med_path())):
559
- print("Warning: MAPAT.MED PATH is missing or invalid. Please check the path configuration.")
605
+ record_startup_warning("Warning: MAPAT.MED PATH is missing or invalid. Please check the path configuration.")
560
606
 
561
607
  # Perform the existing patients check
562
608
  existing_patients, patients_to_process = MediBot_Preprocessor.check_existing_patients(selected_patient_ids, _ac().get_mapat_med_path() if _ac() else '')
@@ -376,6 +376,8 @@ def crosswalk_update(client, config, crosswalk): # Upstream of this is only Medi
376
376
  'medisoft_medicare_id': [] # PERFORMANCE FIX: Use list instead of set to avoid conversions
377
377
  }
378
378
  MediLink_ConfigLoader.log("Initialized payer ID {} in crosswalk with endpoint '{}'.".format(payer_id, selected_endpoint), config, level="DEBUG")
379
+ # TODO (MEDICARE ENDPOINTS): If payer_id is Medicare (e.g., in config['MediLink_Config']['cob_settings']['medicare_payer_ids']),
380
+ # set endpoint to 'MEDICARE_PRIMARY' and optionally store 'crossover_endpoint' for later automation.
379
381
 
380
382
  # Add the insurance ID to the payer ID entry (PERFORMANCE FIX: Use list operations)
381
383
  insurance_id_str = str(insurance_id) # Ensure ID is string
@@ -370,10 +370,12 @@ def save_crosswalk(client, config, crosswalk, skip_api_operations=False, api_cac
370
370
  crosswalk['payer_id'][payer_id]['endpoint'] = select_endpoint(config) # Use the helper function to set the endpoint
371
371
  MediLink_ConfigLoader.log("Initialized 'endpoint' for payer ID {}.".format(payer_id), config, level="DEBUG")
372
372
 
373
- # Initialize medisoft_id and medisoft_medicare_id as empty lists if they do not exist
374
- crosswalk['payer_id'][payer_id].setdefault('medisoft_id', [])
375
- crosswalk['payer_id'][payer_id].setdefault('medisoft_medicare_id', []) # does this work in 3.4.4?
376
- MediLink_ConfigLoader.log("Ensured 'medisoft_id' and 'medisoft_medicare_id' for payer ID {} are initialized.".format(payer_id), config, level="DEBUG")
373
+ # Initialize medisoft_id and medisoft_medicare_id as empty lists if they do not exist
374
+ crosswalk['payer_id'][payer_id].setdefault('medisoft_id', [])
375
+ crosswalk['payer_id'][payer_id].setdefault('medisoft_medicare_id', []) # does this work in 3.4.4?
376
+ MediLink_ConfigLoader.log("Ensured 'medisoft_id' and 'medisoft_medicare_id' for payer ID {} are initialized.".format(payer_id), config, level="DEBUG")
377
+ # TODO (CROSSWALK VALIDATION): Enforce distinctness between 'medisoft_id' and 'medisoft_medicare_id' and support optional
378
+ # 'crossover_endpoint' per payer. Use config['MediLink_Config']['cob_settings']['medicare_payer_ids'] to detect Medicare payers.
377
379
 
378
380
  # Convert sets to sorted lists for JSON serialization
379
381
  for payer_id, details in crosswalk.get('payer_id', {}).items():
@@ -816,6 +816,11 @@ def update_insurance_ids(csv_data, config, crosswalk):
816
816
 
817
817
  # Assign the resolved insurance ID to the row
818
818
  row['Ins1 Insurance ID'] = insurance_id
819
+ # TODO (SECONDARY QUEUE): When building a secondary-claims queue after Medicare crossover,
820
+ # set claim_type='secondary' and attach prior payer fields here from the Medicare primary outcome:
821
+ # - row['prior_payer_name'] = 'MEDICARE'
822
+ # - row['prior_payer_id'] = best Medicare ID from config/crosswalk
823
+ # - optionally row['primary_paid_amount'], row['cas_adjustments'] extracted from 835
819
824
  processed_count += 1
820
825
  # LOGGING STRATEGY: Remove success logging - DEBUG is typically silent anyway
821
826
  # if processed_count <= 10 or processed_count % 100 == 0: # Log first 10 and every 100th
@@ -1,5 +1,5 @@
1
1
  #update_medicafe.py
2
- import subprocess, sys, time, platform, os, shutil
2
+ import subprocess, sys, time, platform, os, shutil, random
3
3
 
4
4
  # Safe import for pkg_resources with fallback
5
5
  try:
@@ -162,6 +162,8 @@ def get_latest_version(package, retries=3, delay=1):
162
162
  time.sleep(delay)
163
163
  return None
164
164
 
165
+
166
+
165
167
  def check_internet_connection():
166
168
  try:
167
169
  requests.get("http://www.google.com", timeout=5)
@@ -288,7 +290,7 @@ def compare_versions(version1, version2):
288
290
  v2_parts = list(map(int, version2.split(".")))
289
291
  return (v1_parts > v2_parts) - (v1_parts < v2_parts)
290
292
 
291
- def upgrade_package(package, retries=3, delay=2): # Updated retries to 3
293
+ def upgrade_package(package, retries=4, delay=2, target_version=None): # Updated retries to 4
292
294
  """
293
295
  Attempts to upgrade the package multiple times with delays in between.
294
296
  """
@@ -296,23 +298,33 @@ def upgrade_package(package, retries=3, delay=2): # Updated retries to 3
296
298
  print_status("No internet connection detected. Please check your internet connection and try again.", "ERROR")
297
299
  print_final_result(False, "No internet connection available")
298
300
 
301
+ # Light verbosity: show pinned target once
302
+ if target_version:
303
+ print("Pinned target version: {}".format(target_version))
304
+
299
305
  for attempt in range(1, retries + 1):
300
- print("Attempt {} to upgrade {}...".format(attempt, package))
306
+ print("Attempt {}/{} to upgrade {}...".format(attempt, retries, package))
301
307
 
302
308
  # Use a more compatible approach for Python 3.4
303
309
  # Try with --no-deps first to avoid dependency resolution issues
310
+ pkg_spec = package
311
+ if target_version:
312
+ pkg_spec = "{}=={}".format(package, target_version)
313
+
304
314
  cmd = [
305
315
  sys.executable, '-m', 'pip', 'install', '--upgrade',
306
- '--no-deps', '--no-cache-dir', '--disable-pip-version-check', '-q', package
316
+ '--no-deps', '--no-cache-dir', '--disable-pip-version-check', '-q', pkg_spec
307
317
  ]
308
318
 
319
+ print("Using pip upgrade with --no-deps and --no-cache-dir")
309
320
  process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
310
321
  stdout, stderr = process.communicate()
311
322
 
312
323
  if process.returncode == 0:
313
324
  print(stdout.decode().strip())
314
325
  new_version = get_installed_version(package) # Get new version after upgrade
315
- if compare_versions(new_version, get_latest_version(package)) >= 0: # Compare versions
326
+ expected_version = target_version or get_latest_version(package)
327
+ if expected_version and compare_versions(new_version, expected_version) >= 0: # Compare versions
316
328
  if attempt == 1:
317
329
  print_status("Upgrade succeeded!", "SUCCESS")
318
330
  else:
@@ -320,20 +332,27 @@ def upgrade_package(package, retries=3, delay=2): # Updated retries to 3
320
332
  time.sleep(delay)
321
333
  return True
322
334
  else:
323
- print_status("Upgrade failed. Current version remains: {}".format(new_version), "WARNING")
335
+ print_status("Upgrade incomplete. Current version: {} Expected at least: {}".format(new_version, expected_version), "WARNING")
324
336
  if attempt < retries:
325
337
  print("Retrying in {} seconds...".format(delay))
326
- time.sleep(delay)
338
+ try:
339
+ time.sleep(delay + (random.random() * 0.5))
340
+ except Exception:
341
+ time.sleep(delay)
327
342
  else:
328
343
  print(stderr.decode().strip())
329
344
  print_status("Attempt {}: Upgrade failed with --no-deps.".format(attempt), "WARNING")
330
345
 
331
346
  # If --no-deps failed, try with --force-reinstall to bypass dependency issues
332
347
  if attempt < retries:
333
- print("Retrying with --force-reinstall...")
348
+ print("Fallback this attempt: retrying with --force-reinstall...")
349
+ pkg_spec = package
350
+ if target_version:
351
+ pkg_spec = "{}=={}".format(package, target_version)
352
+
334
353
  cmd = [
335
354
  sys.executable, '-m', 'pip', 'install', '--upgrade',
336
- '--force-reinstall', '--no-cache-dir', '--disable-pip-version-check', '-q', package
355
+ '--force-reinstall', '--no-cache-dir', '--disable-pip-version-check', '-q', pkg_spec
337
356
  ]
338
357
 
339
358
  process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -342,19 +361,23 @@ def upgrade_package(package, retries=3, delay=2): # Updated retries to 3
342
361
  if process.returncode == 0:
343
362
  print(stdout.decode().strip())
344
363
  new_version = get_installed_version(package)
345
- if compare_versions(new_version, get_latest_version(package)) >= 0:
364
+ expected_version = target_version or get_latest_version(package)
365
+ if expected_version and compare_versions(new_version, expected_version) >= 0:
346
366
  print_status("Attempt {}: Upgrade succeeded with --force-reinstall!".format(attempt), "SUCCESS")
347
367
  time.sleep(delay)
348
368
  return True
349
369
  else:
350
- print_status("Upgrade failed. Current version remains: {}".format(new_version), "WARNING")
370
+ print_status("Upgrade incomplete. Current version: {} Expected at least: {}".format(new_version, expected_version), "WARNING")
351
371
  else:
352
372
  print(stderr.decode().strip())
353
373
  print_status("Attempt {}: Upgrade failed with --force-reinstall.".format(attempt), "WARNING")
354
374
 
355
375
  if attempt < retries:
356
376
  print("Retrying in {} seconds...".format(delay))
357
- time.sleep(delay)
377
+ try:
378
+ time.sleep(delay + (random.random() * 0.5))
379
+ except Exception:
380
+ time.sleep(delay)
358
381
 
359
382
  print_status("All upgrade attempts failed.", "ERROR")
360
383
  return False
@@ -566,7 +589,7 @@ def main():
566
589
  print("Current version: {}".format(current_version))
567
590
  print("Target version: {}".format(latest_version))
568
591
 
569
- if upgrade_package(package):
592
+ if upgrade_package(package, target_version=latest_version):
570
593
  # STEP 8: Verify upgrade
571
594
  debug_step(8, "Upgrade Verification")
572
595
  new_version = get_installed_version(package)
MediCafe/api_core.py CHANGED
@@ -79,6 +79,9 @@ class ConfigLoader:
79
79
  print("Attempting to load Swagger file: {}".format(swagger_path))
80
80
  with open(swagger_path, 'r') as swagger_file:
81
81
  if swagger_path.endswith('.yaml') or swagger_path.endswith('.yml'):
82
+ if yaml is None:
83
+ print("YAML parsing not available (PyYAML not installed). Please install PyYAML or provide a JSON Swagger file.")
84
+ return None
82
85
  print("Parsing YAML file: {}".format(swagger_path))
83
86
  swagger_data = yaml.safe_load(swagger_file)
84
87
  elif swagger_path.endswith('.json'):
MediCafe/graphql_utils.py CHANGED
@@ -109,7 +109,7 @@ class GraphQLQueryBuilder:
109
109
  This is for testing purposes to verify the endpoint is working.
110
110
  """
111
111
  return {
112
- "query": "query Query($input: EligibilityInput!) { checkEligibility(input: $input) { eligibility { eligibilityInfo { trnId member { memberId firstName lastName middleName suffix dateOfBirth gender relationship relationshipCode relationshipTypeCode individualRelationshipCode dependentSequenceNumber } contact { addresses { type street1 street2 city state country zip zip4 } } insuranceInfo { policyNumber eligibilityStartDate eligibilityEndDate planStartDate planEndDate policyStatus planTypeDescription planVariation reportingCode stateOfIssueCode productType productId productCode payerId lineOfBusiness lineOfBusinessCode coverageTypes { typeCode description } } associatedIds { alternateId medicaidRecipientId exchangeMemberId alternateSubscriberId hicNumber mbiNumber subscriberMemberFacingIdentifier survivingSpouseId subscriberId memberReplacementId legacyMemberId customerAccountIdentifier } planLevels { level family { networkStatus planAmount planAmountFrequency remainingAmount } individual { networkStatus planAmount planAmountFrequency remainingAmount } } delegatedInfo { entity payerId contact { phone fax email } addresses { type street1 street2 city state country zip zip4 } } additionalInfo { isReferralRequired } } primaryCarePhysician { isPcpFound lastName firstName middleName phoneNumber address { type street1 street2 city state country zip zip4 } networkStatusCode affiliateHospitalName providerGroupName } coordinationOfBenefit { coordinationOfBenefitDetails { payer { name phoneNumber address { type street1 street2 city state country zip zip4 } } cobPrimacy { indicator description message } } uhgPrimacyStatus { policyEffectiveDate policyTerminationDate primacy { indicator description message } } } idCardImages { side content contentType } providerNetwork { status tier } extendedAttributes { fundingCode fundingType hsa cdhp governmentProgramCode cmsPackageBenefitPlanCode cmsSegmentId cmsContractId marketType obligorId marketSite benefitPlanId virtualVisit planVariation groupNumber legacyPanelNumber coverageLevel sharedArrangement productServiceCode designatedVirtualClinicNetwork medicaidVariableCode healthInsuranceExchangeId memberDiv legalEntityCode } otherBeneficiaries { memberId firstName lastName middleName suffix dateOfBirth gender relationship relationshipCode relationshipTypeCode individualRelationshipCode dependentSequenceNumber } serviceLevels { family { networkStatus services { isVendorOnly service serviceCode serviceDate text status coPayAmount coPayFrequency coInsurancePercent planAmount remainingAmount metYearToDateAmount isReferralObtainedCopay isReferralObtainedCoInsurance referralCopayAmount referralCoInsurancePercent benefitsAllowedFrequencies benefitsRemainingFrequencies message { note { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coPay { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coInsurance { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } deductible { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } benefitsAllowed { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } benefitsRemaining { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coPayList coInsuranceList } } } individual { networkStatus services { isVendorOnly service serviceCode serviceDate text status coPayAmount coPayFrequency coInsurancePercent planAmount remainingAmount metYearToDateAmount isReferralObtainedCopay isReferralObtainedCoInsurance referralCopayAmount referralCoInsurancePercent benefitsAllowedFrequencies benefitsRemainingFrequencies message { note { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coPay { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coInsurance { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } deductible { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } benefitsAllowed { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } benefitsRemaining { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coPayList coInsuranceList } } } } } } }",
112
+ "query": "query Query($input: EligibilityInput!) { checkEligibility(input: $input) { eligibility { eligibilityInfo { trnId member { memberId firstName lastName middleName suffix dateOfBirth gender relationship relationshipCode relationshipTypeCode individualRelationshipCode dependentSequenceNumber } contact { addresses { type street1 street2 city state country zip zip4 } } insuranceInfo { policyNumber eligibilityStartDate eligibilityEndDate planStartDate planEndDate policyStatus planTypeDescription planVariation reportingCode stateOfIssueCode productType productId productCode payerId lineOfBusiness lineOfBusinessCode coverageTypes { typeCode description } } associatedIds { alternateId medicaidRecipientId exchangeMemberId alternateSubscriberId hicNumber mbiNumber subscriberMemberFacingIdentifier survivingSpouseId subscriberId memberReplacementId legacyMemberId customerAccountIdentifier } planLevels { level family { networkStatus planAmount planAmountFrequency remainingAmount } individual { networkStatus planAmount planAmountFrequency remainingAmount } } delegatedInfo { entity payerId contact { phone fax email } addresses { type street1 street2 city state country zip zip4 } } additionalInfo { isReferralRequired } } primaryCarePhysician { isPcpFound lastName firstName middleName phoneNumber address { type street1 street2 city state country zip zip4 } networkStatusCode affiliateHospitalName providerGroupName } coordinationOfBenefit { coordinationOfBenefitDetails { payer { name phoneNumber address { type street1 street2 city state country zip zip4 } } cobPrimacy { indicator description message } } uhgPrimacyStatus { policyEffectiveDate policyTerminationDate primacy { indicator description message } } } idCardImages { side content contentType } providerNetwork { status tier } extendedAttributes { fundingCode fundingType hsa cdhp governmentProgramCode cmsPackageBenefitPlanCode cmsSegmentId cmsContractId marketType obligorId marketSite benefitPlanId virtualVisit planVariation groupNumber legacyPanelNumber coverageLevel sharedArrangement productServiceCode designatedVirtualClinicNetwork medicaidVariableCode healthInsuranceExchangeId memberDiv legalEntityCode } otherBeneficiaries { memberId firstName lastName middleName suffix dateOfBirth gender relationship relationshipCode relationshipTypeCode individualRelationshipCode dependentSequenceNumber } serviceLevels { family { networkStatus services { isVendorOnly service serviceCode serviceDate text status coPayAmount coPayFrequency coInsurancePercent planAmount remainingAmount metYearToDateAmount isReferralObtainedCopay isReferralObtainedCoInsurance referralCopayAmount referralCoInsurancePercent benefitsAllowedFrequencies benefitsRemainingFrequencies message { note { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coPay { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coInsurance { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } deductible { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } benefitsAllowed { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } benefitsRemaining { isSingleMessageDetail isViewDetail messages text subMessages { service status copay msg startDate endDate minCopay minCopayMsg maxCopay maxCopayMsg isPrimaryIndicator } limitationInfo { lmtPeriod lmtType lmtOccurPerPeriod lmtDollarPerPeriod message } isMultipleCopaysFound isMultipleCoinsuranceFound } coPayList coInsuranceList } } } } } } }",
113
113
  "variables": {
114
114
  "input": {
115
115
  "memberId": "0001234567",
@@ -141,7 +141,7 @@ class GraphQLQueryBuilder:
141
141
  Returns the exact GraphQL query format that works with the Super Connector API.
142
142
  This matches the exact format from the successful cURL request.
143
143
  """
144
- return """query Query($input: EligibilityInput!) {\r\n \r\n checkEligibility(input: $input) {\r\n eligibility {\r\n eligibilityInfo {\r\n trnId\r\n member {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n contact {\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n insuranceInfo {\r\n policyNumber\r\n eligibilityStartDate\r\n eligibilityEndDate\r\n planStartDate\r\n planEndDate\r\n policyStatus\r\n planTypeDescription\r\n planVariation\r\n reportingCode\r\n stateOfIssueCode\r\n productType\r\n productId\r\n productCode\r\n payerId\r\n lineOfBusiness\r\n lineOfBusinessCode\r\n coverageTypes {\r\n typeCode\r\n description\r\n }\r\n }\r\n associatedIds {\r\n alternateId\r\n medicaidRecipientId\r\n exchangeMemberId\r\n alternateSubscriberId\r\n hicNumber\r\n mbiNumber\r\n subscriberMemberFacingIdentifier\r\n survivingSpouseId\r\n subscriberId\r\n memberReplacementId\r\n legacyMemberId\r\n customerAccountIdentifier\r\n }\r\n planLevels {\r\n level\r\n family {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n individual {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n }\r\n delegatedInfo {\r\n entity\r\n payerId\r\n contact {\r\n phone\r\n fax\r\n email\r\n }\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n additionalInfo {\r\n isReferralRequired\r\n }\r\n }\r\n primaryCarePhysician {\r\n isPcpFound\r\n lastName\r\n firstName\r\n middleName\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n networkStatusCode\r\n affiliateHospitalName\r\n providerGroupName\r\n }\r\n coordinationOfBenefit {\r\n coordinationOfBenefitDetails {\r\n payer {\r\n name\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n cobPrimacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n uhgPrimacyStatus {\r\n policyEffectiveDate\r\n policyTerminationDate\r\n primacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n }\r\n providerNetwork {\r\n status\r\n tier\r\n }\r\n extendedAttributes {\r\n fundingCode\r\n fundingType\r\n hsa\r\n cdhp\r\n governmentProgramCode\r\n cmsPackageBenefitPlanCode\r\n cmsSegmentId\r\n cmsContractId\r\n marketType\r\n obligorId\r\n marketSite\r\n benefitPlanId\r\n virtualVisit\r\n planVariation\r\n groupNumber\r\n legacyPanelNumber\r\n coverageLevel\r\n sharedArrangement\r\n productServiceCode\r\n designatedVirtualClinicNetwork\r\n medicaidVariableCode\r\n healthInsuranceExchangeId\r\n memberDiv\r\n legalEntityCode\r\n }\r\n otherBeneficiaries {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n serviceLevels {\r\n family {\r\n networkStatus\r\n services {\r\n isVendorOnly\r\n service\r\n serviceCode\r\n serviceDate\r\n text\r\n status\r\n coPayAmount\r\n coPayFrequency\r\n coInsurancePercent\r\n planAmount\r\n remainingAmount\r\n metYearToDateAmount\r\n isReferralObtainedCopay\r\n isReferralObtainedCoInsurance\r\n referralCopayAmount\r\n referralCoInsurancePercent\r\n benefitsAllowedFrequencies\r\n benefitsRemainingFrequencies\r\n message {\r\n note {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPay {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coInsurance {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n deductible {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsAllowed {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsRemaining {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPayList\r\n coInsuranceList\r\n }\r\n }\r\n }\r\n individual {\r\n networkStatus\r\n services {\r\n isVendorOnly\r\n service\r\n serviceCode\r\n serviceDate\r\n text\r\n status\r\n coPayAmount\r\n coPayFrequency\r\n coInsurancePercent\r\n planAmount\r\n remainingAmount\r\n metYearToDateAmount\r\n isReferralObtainedCopay\r\n isReferralObtainedCoInsurance\r\n referralCopayAmount\r\n referralCoInsurancePercent\r\n benefitsAllowedFrequencies\r\n benefitsRemainingFrequencies\r\n message {\r\n note {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPay {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coInsurance {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n deductible {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsAllowed {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsRemaining {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPayList\r\n coInsuranceList\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}"""
144
+ return """query Query($input: EligibilityInput!) {\r\n \r\n checkEligibility(input: $input) {\r\n eligibility {\r\n eligibilityInfo {\r\n trnId\r\n member {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n contact {\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n insuranceInfo {\r\n policyNumber\r\n eligibilityStartDate\r\n eligibilityEndDate\r\n planStartDate\r\n planEndDate\r\n policyStatus\r\n planTypeDescription\r\n planVariation\r\n reportingCode\r\n stateOfIssueCode\r\n productType\r\n productId\r\n productCode\r\n payerId\r\n lineOfBusiness\r\n lineOfBusinessCode\r\n coverageTypes {\r\n typeCode\r\n description\r\n }\r\n }\r\n associatedIds {\r\n alternateId\r\n medicaidRecipientId\r\n exchangeMemberId\r\n alternateSubscriberId\r\n hicNumber\r\n mbiNumber\r\n subscriberMemberFacingIdentifier\r\n survivingSpouseId\r\n subscriberId\r\n memberReplacementId\r\n legacyMemberId\r\n customerAccountIdentifier\r\n }\r\n planLevels {\r\n level\r\n family {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n individual {\r\n networkStatus\r\n planAmount\r\n planAmountFrequency\r\n remainingAmount\r\n }\r\n }\r\n delegatedInfo {\r\n entity\r\n payerId\r\n contact {\r\n phone\r\n fax\r\n email\r\n }\r\n addresses {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n additionalInfo {\r\n isReferralRequired\r\n }\r\n }\r\n primaryCarePhysician {\r\n isPcpFound\r\n lastName\r\n firstName\r\n middleName\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n networkStatusCode\r\n affiliateHospitalName\r\n providerGroupName\r\n }\r\n coordinationOfBenefit {\r\n coordinationOfBenefitDetails {\r\n payer {\r\n name\r\n phoneNumber\r\n address {\r\n type\r\n street1\r\n street2\r\n city\r\n state\r\n country\r\n zip\r\n zip4\r\n }\r\n }\r\n cobPrimacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n uhgPrimacyStatus {\r\n policyEffectiveDate\r\n policyTerminationDate\r\n primacy {\r\n indicator\r\n description\r\n message\r\n }\r\n }\r\n }\r\n providerNetwork {\r\n status\r\n tier\r\n }\r\n extendedAttributes {\r\n fundingCode\r\n fundingType\r\n hsa\r\n cdhp\r\n governmentProgramCode\r\n cmsPackageBenefitPlanCode\r\n cmsSegmentId\r\n cmsContractId\r\n marketType\r\n obligorId\r\n marketSite\r\n benefitPlanId\r\n virtualVisit\r\n planVariation\r\n groupNumber\r\n legacyPanelNumber\r\n coverageLevel\r\n sharedArrangement\r\n productServiceCode\r\n designatedVirtualClinicNetwork\r\n medicaidVariableCode\r\n healthInsuranceExchangeId\r\n memberDiv\r\n legalEntityCode\r\n }\r\n otherBeneficiaries {\r\n memberId\r\n firstName\r\n lastName\r\n middleName\r\n suffix\r\n dateOfBirth\r\n gender\r\n relationship\r\n relationshipCode\r\n relationshipTypeCode\r\n individualRelationshipCode\r\n dependentSequenceNumber\r\n }\r\n serviceLevels {\r\n family {\r\n networkStatus\r\n services {\r\n isVendorOnly\r\n service\r\n serviceCode\r\n serviceDate\r\n text\r\n status\r\n coPayAmount\r\n coPayFrequency\r\n coInsurancePercent\r\n planAmount\r\n remainingAmount\r\n metYearToDateAmount\r\n isReferralObtainedCopay\r\n isReferralObtainedCoInsurance\r\n referralCopayAmount\r\n referralCoInsurancePercent\r\n benefitsAllowedFrequencies\r\n benefitsRemainingFrequencies\r\n message {\r\n note {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPay {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coInsurance {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n deductible {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsAllowed {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n benefitsRemaining {\r\n isSingleMessageDetail\r\n isViewDetail\r\n messages\r\n text\r\n subMessages {\r\n service\r\n status\r\n copay\r\n msg\r\n startDate\r\n endDate\r\n minCopay\r\n minCopayMsg\r\n maxCopay\r\n maxCopayMsg\r\n isPrimaryIndicator\r\n }\r\n limitationInfo {\r\n lmtPeriod\r\n lmtType\r\n lmtOccurPerPeriod\r\n lmtDollarPerPeriod\r\n message\r\n }\r\n isMultipleCopaysFound\r\n isMultipleCoinsuranceFound\r\n }\r\n coPayList\r\n coInsuranceList\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}"""
145
145
 
146
146
  @staticmethod
147
147
  def build_working_eligibility_request(variables):
@@ -424,6 +424,7 @@ class GraphQLResponseTransformer:
424
424
  }
425
425
 
426
426
  # Convenience functions for easy access
427
+
427
428
  def get_eligibility_query():
428
429
  """Get the eligibility GraphQL query (working format)"""
429
430
  return GraphQLQueryBuilder.get_eligibility_query()
@@ -433,7 +434,7 @@ def build_eligibility_variables(**kwargs):
433
434
  return GraphQLQueryBuilder.build_eligibility_variables(**kwargs)
434
435
 
435
436
  def build_eligibility_request(variables):
436
- """Build complete eligibility request body with working format"""
437
+ """Build complete GraphQL request body with working format"""
437
438
  return GraphQLQueryBuilder.build_eligibility_request(variables)
438
439
 
439
440
  def transform_eligibility_response(graphql_response):
@@ -442,4 +443,62 @@ def transform_eligibility_response(graphql_response):
442
443
 
443
444
  def get_sample_eligibility_request():
444
445
  """Get the sample GraphQL request from swagger documentation"""
445
- return GraphQLQueryBuilder.get_sample_eligibility_request()
446
+ return GraphQLQueryBuilder.get_sample_eligibility_request()
447
+
448
+ # -----------------------------------------------------------------------------
449
+ # Phase 2 scaffolding: centralized direct SBR09 extraction (placeholder)
450
+ # -----------------------------------------------------------------------------
451
+
452
+ # Placeholder path for future API-provided SBR09 value.
453
+ # Accepts either a top-level key (e.g., 'sbr09Code') or a dotted path
454
+ # (e.g., 'eligibilityInfo.insuranceInfo.sbr09'). Update when contract is finalized.
455
+ FUTURE_SBR09_FIELD_PATH = '<INSERT_SBR09_FIELD_PATH>'
456
+
457
+
458
+ def _get_nested_value(data, dotted_path):
459
+ """Safely get nested value from dict given a dotted path."""
460
+ try:
461
+ current = data
462
+ for part in dotted_path.split('.'):
463
+ if not isinstance(current, dict) or part not in current:
464
+ return None
465
+ current = current[part]
466
+ return current
467
+ except Exception:
468
+ return None
469
+
470
+
471
+ def _is_valid_sbr09(code):
472
+ if not isinstance(code, str):
473
+ return False
474
+ c = code.strip().upper()
475
+ return 1 <= len(c) <= 3 and c.isalnum()
476
+
477
+
478
+ def _normalize_sbr09(code):
479
+ return str(code).strip().upper()
480
+
481
+
482
+ def extract_sbr09_direct(response_dict):
483
+ """
484
+ Extract SBR09 directly from a transformed GraphQL response or raw GraphQL if the
485
+ provider API supplies it. Returns None until FUTURE_SBR09_FIELD_PATH is set and value is present.
486
+
487
+ - No mapping is performed. Only format checks are applied.
488
+ - Accepts either top-level key or dotted path.
489
+ """
490
+ if not FUTURE_SBR09_FIELD_PATH or FUTURE_SBR09_FIELD_PATH.startswith('<'):
491
+ return None
492
+
493
+ # Try top-level lookup
494
+ raw_value = response_dict.get(FUTURE_SBR09_FIELD_PATH)
495
+
496
+ # If not found, try dotted path
497
+ if raw_value is None and '.' in FUTURE_SBR09_FIELD_PATH:
498
+ raw_value = _get_nested_value(response_dict, FUTURE_SBR09_FIELD_PATH)
499
+
500
+ if raw_value is None:
501
+ return None
502
+
503
+ candidate = _normalize_sbr09(raw_value)
504
+ return candidate if _is_valid_sbr09(candidate) else None