feat: wire Tufts SCO to DentaQuest portal and fix insurance credential dropdown

- Add /dentaquest-eligibility endpoint in Python agent (Tufts SCO uses providers.dentaquest.com)
- Add backend route, processor, and service client for Tufts SCO (separate from UnitedSCO/DentalHub)
- Fix Tufts SCO button to post to new tuftssco route instead of unitedsco
- Fix credential field names: dentaquestUsername/Password (was tuftsscoUsername/Password)
- Fix socket event: listen for selenium:dentaquest_session_started (was unitedsco)
- Fix error visibility: keep session alive 30s on error so backend reads real message
- Replace free-text Site Key field with dropdown to prevent key mismatches

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gitead
2026-04-17 00:59:24 -04:00
parent b6700eceee
commit f5ec4a1480
10 changed files with 591 additions and 61 deletions

View File

@@ -13,12 +13,14 @@ import time
import helpers_ddma_eligibility as hddma
import helpers_deltains_eligibility as hdeltains
import helpers_unitedsco_eligibility as hunitedsco
import helpers_dentaquest_eligibility as hdentaquest
import helpers_cca_eligibility as hcca
# Import startup session-clear functions
from ddma_browser_manager import clear_ddma_session_on_startup
from deltains_browser_manager import clear_deltains_session_on_startup
from unitedsco_browser_manager import clear_unitedsco_session_on_startup
from dentaquest_browser_manager import clear_dentaquest_session_on_startup
from cca_browser_manager import clear_cca_session_on_startup
from dotenv import load_dotenv
@@ -31,6 +33,7 @@ print("=" * 50)
clear_ddma_session_on_startup()
clear_deltains_session_on_startup()
clear_unitedsco_session_on_startup()
clear_dentaquest_session_on_startup()
clear_cca_session_on_startup()
print("=" * 50)
print("SESSION CLEAR COMPLETE")
@@ -341,6 +344,47 @@ async def unitedsco_eligibility(request: Request):
return {"status": "started", "session_id": sid}
async def _dentaquest_worker_wrapper(sid: str, data: dict, url: str):
"""Background worker for DentaQuest (Tufts SCO) — acquires semaphore, updates counters."""
global active_jobs, waiting_jobs
async with semaphore:
async with lock:
waiting_jobs -= 1
active_jobs += 1
try:
await hdentaquest.start_dentaquest_run(sid, data, url)
finally:
async with lock:
active_jobs -= 1
@app.post("/dentaquest-eligibility")
async def dentaquest_eligibility(request: Request):
"""
Starts a DentaQuest (Tufts SCO) 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 = hdentaquest.make_session_entry()
hdentaquest.sessions[sid]["type"] = "dentaquest_eligibility"
hdentaquest.sessions[sid]["last_activity"] = time.time()
async with lock:
waiting_jobs += 1
asyncio.create_task(_dentaquest_worker_wrapper(
sid, data,
url="https://providers.dentaquest.com/"
))
return {"status": "started", "session_id": sid}
async def _cca_worker_wrapper(sid: str, data: dict, url: str):
"""Background worker for CCA — acquires semaphore, updates counters. No OTP."""
global active_jobs, waiting_jobs
@@ -401,6 +445,8 @@ async def submit_otp(request: Request):
res = hdeltains.submit_otp(sid, otp)
elif sid in hunitedsco.sessions:
res = hunitedsco.submit_otp(sid, otp)
elif sid in hdentaquest.sessions:
res = hdentaquest.submit_otp(sid, otp)
else:
raise HTTPException(status_code=404, detail="session not found")
@@ -418,6 +464,8 @@ async def session_status(sid: str):
s = hdeltains.get_session_status(sid)
elif sid in hunitedsco.sessions:
s = hunitedsco.get_session_status(sid)
elif sid in hdentaquest.sessions:
s = hdentaquest.get_session_status(sid)
elif sid in hcca.sessions:
s = hcca.get_session_status(sid)
else: