feat: add Delta Dental Individual (DeltaIndiv) eligibility check flow; fix CCA eligibility false-positive error

CCA step1 was treating the harmless "password set to expire" banner as a
fatal error, closing the browser before the eligibility popup/report
could be captured. Now it short-circuits to success once the patient
popup renders and ignores password-expiration notices.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 15:37:55 -04:00
co-authored by Claude Sonnet 5
parent a5a15d86bc
commit d357edd4a6
15 changed files with 2464 additions and 4 deletions
+56
View File
@@ -15,6 +15,7 @@ from selenium_MHBatchPaymentCheckWorker import AutomationMassHealthBatchPaymentC
import os
import time
import helpers_ddma_eligibility as hddma
import helpers_deltaindiv_eligibility as hdeltaindiv
import helpers_deltains_eligibility as hdeltains
import helpers_unitedsco_eligibility as hunitedsco
import helpers_uniteducard_eligibility as huniteducard
@@ -33,6 +34,7 @@ import helpers_bcbs_ma_eligibility as hbcbs_ma
# Import startup session-clear functions
from ddma_browser_manager import clear_ddma_session_on_startup
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
from uniteducard_browser_manager import clear_uniteducard_session_on_startup
@@ -47,6 +49,7 @@ print("=" * 50)
print("SELENIUM AGENT STARTING - CLEARING SESSIONS")
print("=" * 50)
clear_ddma_session_on_startup()
clear_deltaindiv_session_on_startup()
clear_deltains_session_on_startup()
clear_unitedsco_session_on_startup()
clear_uniteducard_session_on_startup()
@@ -420,6 +423,45 @@ async def ddma_eligibility(request: Request):
return {"status": "started", "session_id": sid}
async def _deltaindiv_worker_wrapper(sid: str, data: dict, url: str):
"""Background worker for Delta Indiv eligibility — acquires semaphore, updates counters."""
global active_jobs, waiting_jobs
async with semaphore:
async with lock:
waiting_jobs -= 1
active_jobs += 1
try:
await hdeltaindiv.start_deltaindiv_run(sid, data, url)
finally:
async with lock:
active_jobs -= 1
@app.post("/deltaindiv-eligibility")
async def deltaindiv_eligibility(request: Request):
"""
Starts a Delta Indiv eligibility session in the background.
Body: { "data": { ... } }
Returns: { status: "started", session_id: "<uuid>" }
"""
global waiting_jobs
body = await request.json()
data = body.get("data", {})
sid = hdeltaindiv.make_session_entry()
hdeltaindiv.sessions[sid]["type"] = "deltaindiv_eligibility"
hdeltaindiv.sessions[sid]["last_activity"] = time.time()
async with lock:
waiting_jobs += 1
# TODO: replace with the real Delta Indiv sign-in URL
asyncio.create_task(_deltaindiv_worker_wrapper(sid, data, url="https://www.deltadentalma.com/sign-in"))
return {"status": "started", "session_id": sid}
async def _deltains_worker_wrapper(sid: str, data: dict, url: str):
"""Background worker for DeltaIns — acquires semaphore, updates counters."""
global active_jobs, waiting_jobs
@@ -1058,6 +1100,8 @@ async def submit_otp(request: Request):
# Try each session store in order
if sid in hddma.sessions:
res = hddma.submit_otp(sid, otp)
elif sid in hdeltaindiv.sessions:
res = hdeltaindiv.submit_otp(sid, otp)
elif sid in hdeltains.sessions:
res = hdeltains.submit_otp(sid, otp)
elif sid in hunitedsco.sessions:
@@ -1095,6 +1139,8 @@ async def session_status(sid: str):
# Try each session store in order
if sid in hddma.sessions:
s = hddma.get_session_status(sid)
elif sid in hdeltaindiv.sessions:
s = hdeltaindiv.get_session_status(sid)
elif sid in hdeltains.sessions:
s = hdeltains.get_session_status(sid)
elif sid in hunitedsco.sessions:
@@ -1144,6 +1190,16 @@ async def clear_ddma_session_endpoint():
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."""
try:
clear_deltaindiv_session_on_startup()
return {"status": "success", "message": "Delta Indiv session cleared"}
except Exception as e:
return {"status": "error", "message": str(e)}
@app.post("/clear-deltains-session")
async def clear_deltains_session_endpoint():
"""Clears the DeltaIns browser session. Call when credentials are deleted or changed."""