1. Cómo funciona (resumen del flujo diario)
A las 6:00pm el Task Scheduler lanza el robot, que hace todo solo:
1Abre/loguea Dentrix
Appointment Book + Office Manager. Si ya está abierto, lo usa.
2Daily Huddle Report con fecha = día siguiente
Preview → manda los route slips al Batch Processor.
3Espera la carga del batch
Espera a que la barra termine de cargar todos los route slips (≥90 s).
4Abre el último route slip
Ctrl+End + Enter → espera el render.
5Imprime a PDF
Microsoft Print to PDF → C:\BCBOT\ROUTESLIPS.pdf (espera a que termine de escribirse).
6Lanza el procesamiento Python
Parsea el route slip, cruza con el roster (member ID) y el crosswalk (payer ID de Stedi), consulta elegibilidad, genera PDFs de cobertura (sin logo de Stedi).
7Manda 2 emails a hello@brandacare.com
[ESCALACIÓN]— los que NO se pudieron verificar (falta dato, inactivo, payer no soportado, a reintentar).[PDF PARA SUBIR]— los verificados OK, con los PDFs adjuntos para subir a Dentrix.
8Cierra ventanas sueltas
Para dejar limpio el día siguiente.
- BC, /BC, INS ACTIVE BC) se saltean = ya verificadas. Cuando el equipo resuelve un escalado, le pone "-BC" para que no se reprocese.
2. Requisitos por cliente
- Máquina Windows en el consultorio con Dentrix instalado y funcionando (idealmente la del front-desk). Acceso remoto (RustDesk / AnyDesk / RDP) para administrarla.
- "Microsoft Print to PDF" disponible (viene con Windows 10/11).
- Cuenta Stedi (BC ClearingHouse) con API key de eligibility.
- Gmail con App Password de 16 caracteres (para mandar los emails).
- Datos del provider: NPI, TIN, razón social.
3. Instalación (una vez por cliente)
3.1 Software
1Instalar Python 3.x
Marcar "Add to PATH". Anotar la ruta del python.exe.
2Instalar librerías
pip install pdfplumber reportlab pypdf
Agregá --break-system-packages si hace falta.
3Instalar AutoHotkey v2
4Explorer → View → File name extensions = ON
Para ver .txt/.ahk reales.
3.2 Carpeta y archivos
- Crear
C:\BCBOT. - Copiar todos los archivos del sistema (ver §10) a
C:\BCBOT. - Ajustar en
run_robot.batyrun_daily.batla ruta alpython.exedel cliente.
3.3 Credenciales (archivos de texto, NUNCA en el código)
Crear en C:\BCBOT (Notepad → Guardar como, tipo "Todos los archivos"):
| Archivo | Contenido |
|---|---|
dentrix_user.txt | usuario de Dentrix |
dentrix_pass.txt | contraseña de Dentrix |
stedi_key.txt | API key de Stedi |
smtp_user.txt | email Gmail (ej. hello@brandacare.com) |
smtp_pass.txt | App Password de Gmail (16 chars, sin espacios) |
dentrix_user*), así que aguanta variaciones chicas de nombre. Aun así, verificá que existan y no estén vacías (si falta dentrix_pass.txt, el login aborta al instante). Riesgo aceptado: la pass de Dentrix queda en texto plano en la máquina.
3.4 Config del provider
En fase0_build_270.py, editar el bloque PROVIDER:
PROVIDER = {
"organizationName": "NOMBRE LEGAL DEL CONSULTORIO",
"npi": "NPI_DEL_PROVIDER",
"taxId": "TIN_SIN_GUION",
}
Y CLINIC en fase0_run.py (nombre corto que aparece en los emails).
4. Datos por cliente (roster + crosswalk de payers)
Esto es lo que hace que el robot verifique a la MAYORÍA, no solo a algunos.
4.1 Roster (member IDs) — reporte "Insurance Carrier List"
En Dentrix → Office Manager → Reports → Reference → Insurance Carrier List:
- Report Type: Dental
- Select Insurance Carrier: From
<ALL>To<ALL>← crítico, para traer TODOS los carriers - List Types: Standard List + Include Subscribers
- Dejar destildado: Include All Insured Patients, Provider IDs, Mailing Labels
- OK → va al Batch Processor → abrir ese item → Print to PDF → guardar como
roster_full.pdf
Parsear a cache:
python fase0_parse_roster.py roster_full.pdf roster_cache.json
Genera roster_cache.json (Chart# → member ID + payer ID + carrier). Refrescalo cada 1–3 meses o cuando entren muchos pacientes nuevos (los nuevos no aparecen hasta re-generar el roster).
4.2 Crosswalk de payers (nombre de carrier → payer ID de Stedi)
El payer ID del roster de Dentrix es basura ("SOURCE") en ~2/3 de los casos, así que el payer ID real se resuelve por el nombre del carrier:
payer_map.csv— lista MAESTRA (carrier → payer ID de Stedi). Fuente principal; mantenela actualizada.carrier_to_payer_REVIEW.csv— crosswalk de los carriers del roster del cliente, auto-mapeado + revisado a mano (columnaFINAL_PAYER_ID).
Prioridad de resolución del payer (ya implementada en fase0_build_270.py):
- Payer REAL del roster del paciente (si es válido, no "SOURCE") — manda.
- Crosswalk revisado por nombre (exacto o sin espacios: "Met life" = "MetLife").
- Match contra
payer_map.csvmaestro (subset de tokens, seguro). - Crosswalk manual local.
4.3 Payers NO soportados por Stedi
En carrier_map.py, mantener la lista de carriers/payers que Stedi no soporta (ej. Solstice / 76578). Esos se escalan directo sin consultar (se verifican en el portal propio del payer). Agregá los que el cliente use y Stedi rechace.
4.4 Self-pay / Medicaid
Se detectan por nombre de carrier y se listan aparte (no se escalan como "falta dato") — no tienen seguro que verificar.
5. Convención de la nota "-BC"
El equipo marca las citas ya verificadas con "BC" suelto en la nota (cualquier variante: -BC, - BC, /BC, INS ACTIVE BC). El robot saltea esas y solo procesa las SIN marca. Entrenar al front-desk en esta convención es parte del onboarding.
NOTES:) como en las notas del paciente (Patient Notes:), y aunque quede en una segunda línea. No confunde BCBS ni IDs tipo BC123 — solo cuenta "BC" como palabra suelta.
6. Automatización
6.1 Auto-login de Windows (recomendado, para caídas)
Si la máquina se reinicia sola, Windows debe quedar logueado para que el robot pueda manejar ventanas. Configurar auto-login (netplwiz → destildar "Users must enter a user name and password", o AutoAdminLogon en el registro).
6.2 Tarea programada a las 6pm
En cmd (como admin):
schtasks /Create /TN "BCBOT Diario" /TR "C:\BCBOT\run_daily.bat" /SC DAILY /ST 18:00 /F
run_daily.bat lanza el robot en modo AUTO (sin carteles) que corre todo y cierra. La tarea es permanente: sobrevive reinicios y corre cada día sola.
7. Los 2 emails (salida diaria)
[ESCALACIÓN] {CLINIC} — {fecha}
Pacientes a resolver a mano, agrupados por motivo (no se pudo verificar / inactivo / payer no soportado / reintentar). El equipo los verifica manual y les pone "-BC".
[PDF PARA SUBIR {CLINIC} {fecha}]
Verificados OK, con los PDFs de cobertura adjuntos (logo de Stedi tapado) para subir al archivo del paciente en Dentrix.
Si el SMTP falla, los emails quedan en C:\BCBOT\out\ (email_1_escalacion.txt, email_2_pdfs_para_subir.txt) y los PDFs en out/ para mandarlos a mano.
8. Alertas
- Si el robot no puede abrir/loguear Dentrix → email
[BCBOT ALERTA]ahello@brandacare.com(revisar la máquina por remoto). - Si el PDF sale vacío (0 KB) → email de alerta (día sin pacientes, o algo se trabó).
9. Mantenimiento y troubleshooting
- Refrescar el roster cada 1–3 meses (§4.1)
- Agregar al crosswalk los carriers nuevos que aparezcan escalados por "falta payer_id"
- Agregar a la lista de no-soportados los payers que Stedi rechace consistentemente
| Síntoma | Causa / Fix |
|---|---|
| Login falla al instante | Falta dentrix_pass.txt (o vacío). Recrearlo. |
| No abre Dentrix | El login se llama distinto ("Appointments, Open" vs "Office Manager, Open"): el robot acepta ambos. Verificar credenciales y ruta de Office.exe. |
| ROUTESLIPS.pdf en 0 KB | Imprimió antes de renderizar, o el archivo estaba abierto en Edge (bloqueado). El robot espera a que el PDF termine de escribirse. Cerrar Edge. |
| Guarda route slip viejo | El batch estaba cargando aún. El robot espera ≥90 s tras Preview. |
| Emojis rompen el log | Resuelto (prints en ASCII + PYTHONIOENCODING=utf-8). |
| Payer cambia entre corridas | Resuelto: el payer del roster manda sobre la adivinanza por nombre. |
| "falta member_id" | Paciente no está en el roster (nuevo) → refrescar roster, o cargar el seguro en Dentrix. El route slip NO imprime el member ID. |
| "DESCONOCIDO" | El payer respondió pero no determinó cobertura (a veces payer ID de otro estado, ej. BCBS). Revisar a mano. |
| "payer no soportado" | Stedi no soporta ese payer (ej. Solstice). Verificar en el portal del payer. |
| HTTP 401 Stedi | La API key necesita prefijo Key (ya contemplado). Regenerar key si sigue. |
| SMTP 535 | Regenerar el App Password de Gmail (16 chars, sin espacios). |
10. Inventario de archivos (C:\BCBOT)
Robot / automatización
| Archivo | Función |
|---|---|
robot.ahk | Robot AutoHotkey (login + descarga + orquestación). TEST_DATE="" = día siguiente. |
run_daily.bat | Lanza el robot en modo AUTO (lo dispara el Task Scheduler). |
run_robot.bat | Corre solo el procesamiento Python sobre ROUTESLIPS.pdf. |
alert_login.py / alert_login.bat | Email de alerta si no puede abrir Dentrix. |
Pipeline Python
| Archivo | Función |
|---|---|
fase0_run.py | Orquestador (parsea, verifica, arma emails). CLINIC acá. |
fase0_parse_route_slip.py / fase0_parse_schedule.py | Parser de route slips. |
fase0_parse_roster.py | Parser del "Insurance Carrier List" → roster_cache.json. |
fase0_build_270.py | Join route slip + roster + crosswalk → request 270 (config PROVIDER acá). |
carrier_map.py | Crosswalk carrier → payer ID (roster + maestro), self-pay, no-soportados. |
stedi_client.py | Llamadas a Stedi (elegibilidad + PDF de cobertura). |
pdf_postprocess.py | Tapa el logo de Stedi. |
fase0_pdf.py | PDF de respaldo si el de Stedi falla. |
fase0_email.py | Arma y manda los 2 emails. |
Datos
| Archivo | Función |
|---|---|
roster_cache.json | Roster parseado (Chart# → member ID + payer ID). |
payer_map.csv | Lista maestra carrier → payer ID de Stedi. |
carrier_to_payer_REVIEW.csv | Crosswalk revisado del cliente. |
Credenciales (§3.3) — 5 archivos .txt.
Salida — C:\BCBOT\out\ (logs, emails en .txt, PDFs de cobertura).
11. Checklist de onboarding de un cliente nuevo
| # | Paso |
|---|---|
| 1 | Acceso remoto a la máquina con Dentrix |
| 2 | Python + AutoHotkey v2 instalados; ruta de python.exe en los .bat |
| 3 | C:\BCBOT con todos los archivos (§10) |
| 4 | 5 archivos de credenciales creados |
| 5 | PROVIDER (NPI/TIN/nombre) y CLINIC configurados |
| 6 | Roster generado (Insurance Carrier List, ALL) → roster_cache.json |
| 7 | Crosswalk de payers revisado (carrier_to_payer_REVIEW.csv) |
| 8 | Lista de payers no-soportados del cliente |
| 9 | Front-desk entrenado en la convención "-BC" |
| 10 | Auto-login de Windows configurado |
| 11 | Tarea de las 6pm programada (schtasks) |
| 12 | Corrida de prueba OK (llegan los 2 emails, PDFs con peso real) |
