feat: MH eligibility & history, CMSP eligibility & history & remaining

- Add MH Eligibility & History button: runs full MH eligibility flow then
  clicks member ID → service history, prints both PDFs via CDP, opens
  dual side-by-side PDF modal (eligibility auto-downloads, history does not)
- Add CMSP Eligibility & History & Remaining button: same flow plus
  navigates back to member details, clicks View Accumulator, prints
  accumulator PDF via CDP; opens 3-panel side-by-side PDF modal
- Generalize DualPdfPreviewModal to accept panels[] array (works for 2 or 3 PDFs)
- Auto-download eligibility PDF via direct API URL to avoid Chrome Safe
  Browsing pause on blob: URL downloads
- New backend processors, job types, and routes for both flows
- New Python Selenium workers with stable CSS selectors (ng-bind, href*)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gitead
2026-05-13 23:29:55 -04:00
parent 131733564e
commit 06526cd1bc
11 changed files with 1868 additions and 2 deletions

View File

@@ -6,6 +6,8 @@ import uvicorn
import asyncio
from selenium_claimSubmitWorker import AutomationMassHealthClaimsLogin
from selenium_eligibilityCheckWorker import AutomationMassHealthEligibilityCheck
from selenium_MH_eligibilityHistoryCheckWorker import AutomationMassHealthEligibilityHistoryCheck
from selenium_CMSP_eligibilityHistoryRemainingCheckWorker import AutomationCMSPEligibilityHistoryRemainingCheck
from selenium_claimStatusCheckWorker import AutomationMassHealthClaimStatusCheck
from selenium_preAuthWorker import AutomationMassHealthPreAuth
from selenium_MHPaymentCheckWorker import AutomationMassHealthPaymentCheck
@@ -135,6 +137,83 @@ async def start_workflow(request: Request):
async with lock:
active_jobs -= 1
# Endpoint: 2a — MH Eligibility + Service History
@app.post("/mh-eligibility-history-check")
async def mh_eligibility_history_check(request: Request):
global active_jobs, waiting_jobs
data = await request.json()
async with lock:
waiting_jobs += 1
async with semaphore:
async with lock:
waiting_jobs -= 1
active_jobs += 1
try:
bot = AutomationMassHealthEligibilityHistoryCheck(data)
result = bot.main_workflow("https://provider.masshealth-dental.org/mh_provider_login")
if result.get("status") == "error":
return {"status": "error", "message": result.get("message")}
port = os.getenv("PORT", "5002")
url_host = os.getenv("HOST", "localhost")
if result.get("pdf_path"):
filename = os.path.basename(result["pdf_path"])
result["pdf_url"] = f"http://{url_host}:{port}/downloads/{filename}"
if result.get("history_pdf_path"):
filename = os.path.basename(result["history_pdf_path"])
result["history_pdf_url"] = f"http://{url_host}:{port}/downloads/{filename}"
return result
except Exception as e:
return {"status": "error", "message": str(e)}
finally:
async with lock:
active_jobs -= 1
# Endpoint: 2b — CMSP Eligibility + Service History + Accumulator (Remaining)
@app.post("/cmsp-eligibility-history-remaining-check")
async def cmsp_eligibility_history_remaining_check(request: Request):
global active_jobs, waiting_jobs
data = await request.json()
async with lock:
waiting_jobs += 1
async with semaphore:
async with lock:
waiting_jobs -= 1
active_jobs += 1
try:
bot = AutomationCMSPEligibilityHistoryRemainingCheck(data)
result = bot.main_workflow("https://provider.masshealth-dental.org/mh_provider_login")
if result.get("status") == "error":
return {"status": "error", "message": result.get("message")}
port = os.getenv("PORT", "5002")
url_host = os.getenv("HOST", "localhost")
for key, url_key in [
("pdf_path", "pdf_url"),
("history_pdf_path", "history_pdf_url"),
("accumulator_pdf_path", "accumulator_pdf_url"),
]:
if result.get(key):
filename = os.path.basename(result[key])
result[url_key] = f"http://{url_host}:{port}/downloads/{filename}"
return result
except Exception as e:
return {"status": "error", "message": str(e)}
finally:
async with lock:
active_jobs -= 1
# Endpoint: 2.1 — Start the automation for Claims login (open browser and log in)
@app.post("/claims-login")
async def start_claims_login(request: Request):