> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Arquitectura de Reporter

> Cómo funciona Reporter: un binario cuyo RUN_MODE selecciona la superficie de la API, la superficie del worker o ambas, la cola entre ellas y los almacenes que comparten.

Reporter se distribuye como **un solo binario**. `RUN_MODE` selecciona qué superficies sirve ese binario: `api`, `worker` o `all`. La API y el worker son dos roles del mismo programa, no dos productos. Comparten una compilación, una versión y un release.

Eliges una topología en el momento del despliegue configurando una variable de entorno.

## Dos superficies, un binario

***

| Superficie | `RUN_MODE` | Sirve                                                                                                                         |
| ---------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| API        | `api`      | Todas las operaciones REST en el puerto `4005`, además de `/health`, `/readyz` y `/version`.                                  |
| Worker     | `worker`   | Sin superficie REST. Consume la cola de informes. Un pequeño servidor de salud en `HEALTH_PORT` expone `/health` y `/readyz`. |
| Ambas      | `all`      | Ambas superficies en un solo proceso.                                                                                         |

```bash theme={null}
# API surface
RUN_MODE=api
SERVER_ADDRESS=:4005

# Worker surface
RUN_MODE=worker
HEALTH_PORT=4006
```

Usa `all` cuando un solo proceso es suficiente, la opción habitual para el desarrollo local y los despliegues pequeños. Separa los roles en dos unidades desplegables cuando la generación de informes necesite escalar por su cuenta. Renderizar un PDF grande cuesta mucho más que aceptar la solicitud que lo pidió. Los despliegues separados permiten dimensionar cada lado según su propia carga.

## El recorrido de un informe

***

<Steps>
  <Step title="La API acepta la solicitud">
    Un `POST` a `/v1/reports` indica una plantilla y sus filtros. Reporter toma primero un bloqueo de idempotencia. La clave del bloqueo es el encabezado `X-Idempotency` cuando envías uno, y un hash del cuerpo de la solicitud cuando no. Reporter rechaza un duplicado que todavía está en curso. Un duplicado de una solicitud completada repite el informe original y marca la respuesta como una repetición.
  </Step>

  <Step title="La API valida y persiste">
    Reporter carga el mapa de campos y el formato de salida de la plantilla. Luego verifica los campos de filtro contra el esquema activo de cada fuente de datos, y escribe el informe con estado `Processing`.
  </Step>

  <Step title="La API encola el trabajo">
    Publica un mensaje de comando en la cola interna de RabbitMQ y responde `201 Created` con el informe en `Processing`. Quien hizo la llamada no tiene nada más que hacer. El renderizado aún no empezó.
  </Step>

  <Step title="El worker renderiza">
    El worker consume el comando. Omite el comando si el informe ya quedó resuelto como `Finished` o `Error`. Carga la plantilla desde el almacenamiento de objetos y extrae los datos de cada fuente de datos. Renderiza el documento y lo convierte a PDF cuando el formato lo requiere. Sube el artefacto.
  </Step>

  <Step title="El worker resuelve el estado">
    Escribe `Finished`, `Partial` o `Error` y emite el evento correspondiente. La operación de descarga entrega el artefacto una vez que el informe está `Finished`.
  </Step>
</Steps>

## La cola entre ambas

***

La API y el worker se comunican mediante una cola de RabbitMQ que lleva los comandos de informes en una sola dirección, con una dead-letter queue detrás. Esta cola funciona como plomería interna entre las dos superficies del mismo binario. No es un punto de integración, no lleva ningún contrato sobre el que se recomiende construir, y su exchange, su cola y su routing key son todos configurados por el operador.

Los eventos de negocio son un canal separado. Reporter los publica en su propio exchange, que el operador configura y que el valor de referencia del despliegue llama `reporter.events`. Cada emisión ocurre después del commit de la base de datos y nunca hace fallar el trabajo que la produjo. Los eventos de alto valor pasan por un outbox duradero en lugar de una publicación directa, de modo que una interrupción del broker los retrasa en lugar de perderlos.

## Extracción de datos

***

El worker no se comunica con tus bases de datos mediante consultas escritas a mano. Ejecuta su motor de extracción incorporado, sin ningún salto de red hacia un servicio separado.

El motor limita cada ejecución. Los valores predeterminados permiten 10 fuentes de datos por informe, 50 tablas por fuente de datos y 200 campos por tabla. También permiten extraer cuatro fuentes de datos en paralelo, y un plazo de cinco minutos para toda la extracción. Los fallos no terminan la ejecución. Un informe cuyas secciones tienen éxito parcial se renderiza con lo que tiene. Queda resuelto como `Partial` y registra qué secciones fallaron.

## Almacenes y artefactos

***

| Dependencia                                 | Rol                                                                                        |
| ------------------------------------------- | ------------------------------------------------------------------------------------------ |
| MongoDB                                     | Plantillas, informes, plazos y el outbox de eventos.                                       |
| RabbitMQ                                    | La cola interna de informes y el exchange de eventos de negocio.                           |
| Redis o Valkey                              | Bloqueos de idempotencia, la caché de esquemas y las señales del ciclo de vida del tenant. |
| Almacenamiento de objetos compatible con S3 | Archivos de plantillas y artefactos renderizados, en un solo bucket.                       |

El almacenamiento de objetos es compatible con S3: Reporter habla el protocolo S3 y cualquier servicio que lo responda funciona como destino. Las fuentes de las plantillas quedan bajo el prefijo `templates/`, y los artefactos renderizados bajo `reports/`, indexados por el identificador de la plantilla y del informe, con el formato de salida como extensión. Reporter no aplica ninguna expiración propia, así que la retención es una política de ciclo de vida que defines en el bucket.

## Reporter y Midaz

***

Midaz es una **fuente de datos** para Reporter, no una dependencia en tiempo de ejecución. Reporter no lleva código específico de Midaz. Registras una base de datos de Midaz con las mismas variables `DATASOURCE_*` que cualquier otra base de datos PostgreSQL. Las plantillas la dirigen mediante el `configName` que eligió el operador.

De esto se siguen dos consecuencias. Reporter arranca y sirve plantillas, plazos y métricas sin ninguna fuente de datos configurada, de modo que una interrupción de Midaz nunca detiene la ejecución de Reporter. Y el mismo despliegue puede generar informes sobre Midaz, sobre tus propias bases de datos, o sobre ambas en una misma plantilla.

Apunta Reporter a una réplica de lectura donde exista una. La vía de extracción solo lee, pero la carga de consultas de un informe pesado es real, y una réplica la mantiene fuera de la vía de escritura del ledger.

<Note>
  Consulta [Cómo conectar Reporter con Midaz](/es/products/reporter/connecting-reporter-to-midaz) para conocer las variables, la convención de `configName` y cómo confirmar que la fuente es visible.
</Note>

## Salud y readiness

***

Ambas superficies exponen `/health` y `/readyz` antes de la autenticación, así que las sondas las alcanzan sin necesidad de un token. La sonda `/health` responde 503 hasta que la autosonda de inicio se completa correctamente. Esto permite que un orquestador reinicie un pod que no pudo alcanzar sus dependencias al arrancar. La sonda `/readyz` informa las dependencias que esa superficie realmente usa, y su respuesta indica en qué modo de despliegue se ejecuta el proceso. La superficie de la API también sirve `/version` con la procedencia de la compilación.

Consulta la [referencia de salud y readiness](/es/reference/health-and-readiness) para conocer el contrato de sondas compartido entre los productos de Lerian.

## Próximos pasos

***

<CardGroup cols={2}>
  <Card title="Conceptos centrales" icon="cubes" href="/es/products/reporter/reporter-core-concepts">
    Plantillas, fuentes de datos, informes, plazos y los cuatro estados del informe.
  </Card>

  <Card title="Variables de entorno" icon="gear" href="/es/products/reporter/reporter-environment-variables">
    Todos los ajustes que dan forma a un despliegue de Reporter.
  </Card>
</CardGroup>
