> ## 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 corre Reporter: un binario cuyo RUN_MODE selecciona la superficie de API, la superficie de worker o ambas, la cola entre ellas y los almacenes que comparten.

Reporter se distribuye como **un 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, y se construyen, se versionan y se publican juntos.

Ese solo hecho da forma a todo lo demás en esta página. Eliges una topología en el momento del despliegue definiendo una variable de entorno, no ensamblando servicios separados.

## Dos superficies, un binario

***

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

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

# Superficie de worker
RUN_MODE=worker
HEALTH_PORT=4006
```

Usa `all` cuando un solo proceso alcanza, que es la elección habitual para desarrollo local y despliegues pequeños. Separa los roles en dos desplegables cuando la generación de informes necesita escalar por su cuenta: renderizar un PDF grande cuesta mucho más que aceptar la solicitud que lo pidió, y despliegues separados te dejan dimensionar cada lado según su propia carga.

## El camino que recorre un informe

***

<Steps>
  <Step title="La API acepta la solicitud">
    Un `POST` a `/v1/reports` nombra una plantilla y sus filtros. Reporter toma primero un bloqueo de idempotencia, con clave en la cabecera `X-Idempotency` cuando la envías y en un hash del cuerpo de la solicitud cuando no. Un duplicado que sigue en vuelo se rechaza; un duplicado de una solicitud completada reproduce 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, contrasta los campos de filtro con el esquema en vivo 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 llamó terminó aquí. El renderizado todavía no empezó.
  </Step>

  <Step title="El worker renderiza">
    El worker consume el comando, lo omite si el informe ya quedó en `Finished` o `Error`, carga la plantilla desde el almacenamiento de objetos, extrae los datos de cada fuente de datos, renderiza el documento, lo convierte a PDF cuando el formato lo pide y sube el artefacto.
  </Step>

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

## La cola entre ellas

***

La API y el worker se comunican sobre una cola de RabbitMQ que lleva comandos de informe en un solo sentido, con una cola de mensajes muertos detrás. Esa cola es plomería privada entre las dos superficies del mismo binario. No es un punto de integración, no lleva ningún contrato sobre el que debas construir, y su exchange, su cola y su routing key se configuran desde el entorno.

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

## Extracción de datos

***

El worker no habla con tus bases de datos mediante consultas escritas a mano. Ejecuta el mismo motor de extracción que impulsa a [Fetcher](/es/fetcher/fetcher-core-concepts), embebido en proceso, sin ningún salto de red a un servicio aparte.

El motor acota cada ejecución. Los valores por defecto permiten 10 fuentes de datos por informe, 50 tablas por fuente de datos, 200 campos por tabla, cuatro fuentes de datos extraídas en paralelo y un plazo de cinco minutos para toda la extracción. Los fallos se acumulan en lugar de ser fatales: un informe cuyas secciones tienen éxito solo en parte se renderiza con lo que tiene y se asienta como `Partial`, registrando 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 de ciclo de vida de tenant. |
| Almacenamiento de objetos compatible con S3 | Los archivos de plantilla y los 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 plantilla aterrizan bajo el prefijo `templates/`, y los artefactos renderizados bajo `reports/`, con los identificadores de plantilla y de informe y 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 de ejecución. Reporter no lleva código específico de Midaz: una base de datos de Midaz se registra con las mismas variables `DATASOURCE_*` que cualquier otra base PostgreSQL, y las plantillas la direccionan por el `configName` que eligió el operador.

De ahí se siguen dos consecuencias. Reporter arranca y sirve plantillas, plazos y métricas sin ninguna fuente de datos configurada, así que una caída de Midaz nunca impide que Reporter corra. Y el mismo despliegue puede reportar sobre Midaz, sobre tus propias bases de datos y sobre ambas en una sola plantilla.

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

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

## Salud y readiness

***

Las dos superficies exponen `/health` y `/readyz` antes de la autenticación, así que las sondas llegan sin token. `/health` responde 503 hasta que la autoprueba de arranque tiene éxito, lo que permite a un orquestador reiniciar un pod que no pudo alcanzar sus dependencias al iniciar. `/readyz` reporta las dependencias que esa superficie usa de verdad, y su respuesta indica en qué modo de despliegue corre el proceso. La superficie de API también sirve `/version` con la procedencia del build.

Lee la [referencia de salud y readiness](/es/reference/health-and-readiness) para el contrato de sondas que comparten los productos de Lerian.

## Próximos pasos

***

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

  <Card title="Variables de entorno" icon="gear" href="/es/reporter/reporter-environment-variables">
    Cada ajuste que da forma a un despliegue de Reporter.
  </Card>
</CardGroup>
