Autenticación, Límites de Tasa y Exportaciones
Hola Doc expone su API a públicos muy distintos —el portal interno, el POS de venta, las terminales de cabina, el acceso móvil y otro microservicio— y cada uno entra por una frontera de autenticación separada, con su propia resolución de inquilino y su propio límite de tasa. Mantener esas fronteras claras es una regla central del servicio. Esta página las describe; los permisos del portal interno están en Permisos y navegación.
Las cinco fronteras
Sección titulada «Las cinco fronteras»| Frontera | Credencial | Inquilino | Endpoints | Límite de tasa |
|---|---|---|---|---|
| Sesión de portal | JWT del portal | Claims del token | Todas las rutas protegidas del portal | — |
| API key externa (POS) | Encabezado X-Api-Key | Metadatos de la API key | Ingesta de transacciones, lookup de registro, agente de exportación | 60 req/min por API key |
| Servicio a servicio | X-Api-Key + X-Tenant-Id | Encabezado X-Tenant-Id | Descarga interna de exportaciones (alcance hola-doc.exports.read) | — |
| Token de cabina | Bearer cab_… (token largo, almacenado con hash) | Registro de la cabina | Info y verificación de cabina | 10 req/min por cabina |
| QR móvil (público) | Ninguna; el ID de cabina va en la URL | Registro de la cabina | Info y verificación móvil | 2 req/min por IP+cabina y 3 intentos fallidos / 15 min |
Notas de comportamiento:
- La frontera del token de cabina valida además una lista de IP/CIDR permitidas por sitio: si el sitio define
allowed_cidrs, se rechaza el acceso desde fuera del rango. - En el límite móvil de intentos fallidos, solo las verificaciones fallidas consumen cupo; una verificación exitosa no descuenta.
- Los límites de tasa usan Redis cuando está disponible y, si no, un cubo de fichas en memoria. En modo no productivo el limitador está desactivado salvo que se fuerce.
- En cada petición autenticada con token de cabina se actualiza
last_seen_atde la cabina de forma asíncrona (latido / heartbeat).
Aislamiento por inquilino
Sección titulada «Aislamiento por inquilino»Toda consulta queda acotada por tenant_id, sin importar la frontera: el portal lo toma de los claims, la API key de sus metadatos, el servicio a servicio del encabezado X-Tenant-Id y la cabina de su registro. No se cruzan datos entre inquilinos.
Agente de exportación (pull)
Sección titulada «Agente de exportación (pull)»Las exportaciones de tipo agente funcionan por extracción (pull): un proceso externo, autenticado con API key externa, pide y descarga los archivos.
graph TD
A[GET /export-agent/config] --> B[POST /export-agent/runs]
B --> C[GET /export-agent/runs/:id/file]
C --> D[POST /export-agent/runs/:id/ack]
D --> E[Se confirman los hashes<br/>y se marca descargado]
| Método y ruta | Acción |
|---|---|
GET /export-agent/config | Configuración del proveedor (formato, modo de entrega). |
POST /export-agent/runs | Disparar una corrida (idempotente por clientRunId). |
GET /export-agent/runs/:id/file | Descargar el archivo (XLSX) cuando la corrida fue exitosa. |
POST /export-agent/runs/:id/ack | Confirmar la descarga con el SHA-256 del archivo. |
Los modos de entrega son dos: correo (publica un evento para que Comunicaciones lo envíe) y agente (deja los hashes en preparación y los confirma solo tras el ack). El programador que dispara las corridas según el horario del proveedor se describe en Trabajos programados.
Retención: el contenido del archivo se conserva como máximo 24 horas; el ciclo diario borra el file_data más antiguo y deja solo los metadatos para auditoría.
Casos esperados en pruebas
Sección titulada «Casos esperados en pruebas»- Una API key externa supera su cupo y recibe el rechazo por límite de tasa a los 60 req/min.
- Una cabina fuera de la lista de CIDR permitidos se rechaza aunque el token sea válido.
- En el móvil, los intentos fallidos consumen cupo; uno exitoso no.
- Una corrida de exportación repetida con el mismo
clientRunIdno se duplica. - El contenido de una exportación de más de 24 horas queda sin
file_data.