2026-07-17 12:21:31 -05:00
# Módulos
| Archivo | Función |
|---|---|
2026-08-31 12:31:48 -05:00
| `main.py` | Daemon orquestador. Bucle infinito con horarios configurables (`scheduler.json` ), obtiene token, consulta HANA, procesa pendientes (nuevos + reintentos). |
2026-08-04 10:51:15 -05:00
| `get_token_headless.py` | Login headless via Firefox real. Sin ventana visible. |
2026-07-17 12:21:31 -05:00
| `get_token.py` | Login SOL via Playwright (headless=False). Navega menú → extrae JWT de `sessionStorage['SUNAT.token']` . |
| `consulta_cpe.py` | Consulta API REST `api-cpe.sunat.gob.pe` . Retorna `(data, status_code)` . Lanza `TokenExpiredError` en 401. |
| `hana_manager.py` | Conexión HANA vía `hdbcli` . Consulta pendientes en `OPCH` , actualiza flags de descarga. |
| `gestor_fallas.py` | SQLite `fallas_descarga.db` . Registro de fallas con conteo de intentos y backoff progresivo (0min → 5min → 15min → ... → 12h, máx 20). |
2026-08-31 12:31:48 -05:00
| `historial_manager.py` | SQLite `historial.db` . Registra cada intento de consulta/descarga (éxito o falla) para auditoría; limpia registros de más de 180 días. Incluye CLI (`python historial_manager.py --ruc/--serie/--numero/--tipo` ) para buscar intentos. |
| `logger_manager.py` | Logging con formato de árbol (indentado por tareas anidadas) a consola + archivo. Rotación diaria en `logs/sunat_YYYY-MM-DD.log` , limpieza automática de logs con más de 7 días. |
2026-07-17 12:21:31 -05:00
| `smb_manager.py` | Monta recurso SMB (`mount_smbfs` /`mount.cifs` /`net use` ) y sincroniza PDF/XML al NAS. Limpia JSON/ZIP temporales. |
2026-08-31 12:31:48 -05:00
| `scheduler.json` | Horarios activos (`HORARIOS` ) y días de la semana en que corre el daemon (`DIAS_ACTIVOS` ). Editable sin tocar código. |
2026-07-17 12:21:31 -05:00
| `token.json` | Token JWT auto-generado con expiración. |
| `.env` | Credenciales HANA y SUNAT. |
## Flujo
2026-08-31 12:31:48 -05:00
1. `main.py` verifica día/horario (`scheduler.json` ) → renueva token si expiró (get_token_headless → get_token.py headless=False)
2026-07-17 12:21:31 -05:00
2. `obtener_pendientes()` trae todos los documentos de OPCH donde `tienePDF='N'` o `tieneXML='N'`
3. Separa en **nuevos** (no están en fallas DB) y **reintentos** (fallas pendientes con backoff cumplido)
4. Por cada doc:
- `consultar_cpe()` → si 401, renueva token y reintenta
- Si falla (500/404/etc) → `registrar_falla()` con backoff progresivo
- Si OK → `descargar_archivo()` (XML + PDF + CDR)
- `marcar_pdf_descargado()` / `marcar_xml_descargado()` actualizan HANA
- Si era reintento exitoso → `eliminar_falla()`
2026-08-31 12:31:48 -05:00
- `registrar_intento()` deja constancia del resultado en `historial.db`
2026-07-17 12:21:31 -05:00
5. `sincronizar_a_smb()` monta NAS (si no está montado), copia PDF/XML via rsync (Mac/Linux) o shutil.move (Windows), y elimina JSON/ZIP temporales de `descargas/`
2026-08-31 12:31:48 -05:00
6. Espera intervalo configurado (según `scheduler.json` , ej. 5 min modo rápido, 30 min/1 h modo full) y repite
Al arrancar, `main.py` también corre mantenimiento: `limpiar_logs_antiguos(dias=7)` y `limpiar_historial_antiguo(dias=180)` .