feat: BCBS MA persistent session, Expand All fix, address/gender extraction

- Persistent Chrome profile (bcbs_ma_browser_manager) reused across patients;
  login probes /myportal/ to skip login + OTP while the session is active
- Expand All: JS-click the expandCollapseViews span, verify sections opened,
  and unclip fixed-height result tables so the PDF includes every row
- Extract patient address and gender from the results page and save to patient
- Uppercase member IDs (XXA...), matching older lowercase records
- Add /clear-bcbs-ma-session endpoint

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 18:27:46 -04:00
co-authored by Claude Opus 5.5
parent 011869f641
commit 13be6e97d5
6 changed files with 474 additions and 89 deletions
+13 -2
View File
@@ -37,6 +37,7 @@ import helpers_metlife_claim as hmetlife_claim
# Import startup session-clear functions
from ddma_browser_manager import clear_ddma_session_on_startup
from bcbs_ma_browser_manager import clear_bcbs_ma_session
from deltaindiv_browser_manager import clear_deltaindiv_session_on_startup
from deltains_browser_manager import clear_deltains_session_on_startup
from unitedsco_browser_manager import clear_unitedsco_session_on_startup
@@ -792,7 +793,7 @@ async def cca_eligibility(request: Request):
async def _bcbs_ma_worker_wrapper(sid: str, data: dict, url: str):
"""Background worker for BCBS MA eligibility — fresh browser, always OTP."""
"""Background worker for BCBS MA eligibility — persistent browser, OTP only when login expired."""
global active_jobs, waiting_jobs
async with semaphore:
async with lock:
@@ -809,7 +810,7 @@ async def _bcbs_ma_worker_wrapper(sid: str, data: dict, url: str):
async def bcbs_ma_eligibility(request: Request):
"""
Starts a BCBS MA eligibility session in the background.
Fresh Chrome each time — no persistent session (OTP always required).
Persistent Chrome profile — OTP only when the BCBS MA login has expired.
Body: { "data": { memberId, dateOfBirth, firstName, lastName, bcbsMaUsername, bcbsMaPassword } }
Returns: { status: "started", session_id: "<uuid>" }
"""
@@ -1322,6 +1323,16 @@ async def clear_ddma_session_endpoint():
return {"status": "error", "message": str(e)}
@app.post("/clear-bcbs-ma-session")
async def clear_bcbs_ma_session_endpoint():
"""Clears the BCBS MA browser session. Call when credentials are deleted or changed."""
try:
clear_bcbs_ma_session()
return {"status": "success", "message": "BCBS MA session cleared"}
except Exception as e:
return {"status": "error", "message": str(e)}
@app.post("/clear-deltaindiv-session")
async def clear_deltaindiv_session_endpoint():
"""Clears the Delta Indiv browser session. Call when credentials are deleted or changed."""