> ## 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.

# Arquitetura do Reporter

> Como o Reporter roda: um binário cujo RUN_MODE seleciona a superfície de API, a superfície de worker ou ambas, a fila entre elas e os armazenamentos que elas compartilham.

O Reporter é entregue como **um binário**. O `RUN_MODE` seleciona quais superfícies esse binário atende: `api`, `worker` ou `all`. A API e o worker são dois papéis do mesmo programa, não dois produtos, e são construídos, versionados e lançados juntos.

Esse único fato molda todo o resto desta página. Você escolhe uma topologia no momento da implantação definindo uma variável de ambiente, não montando serviços separados.

## Duas superfícies, um binário

***

| Superfície | `RUN_MODE` | Atende                                                                                                                              |
| ---------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| API        | `api`      | Todas as operações REST na porta `4005`, mais `/health`, `/readyz` e `/version`.                                                    |
| Worker     | `worker`   | Nenhuma superfície REST. Consome a fila de relatórios. Um pequeno servidor de saúde em `HEALTH_PORT` carrega `/health` e `/readyz`. |
| Ambas      | `all`      | As duas superfícies em um único processo.                                                                                           |

```bash theme={null}
# Superfície de API
RUN_MODE=api
SERVER_ADDRESS=:4005

# Superfície de worker
RUN_MODE=worker
HEALTH_PORT=4006
```

Rode `all` quando um processo é suficiente, que é a escolha usual para desenvolvimento local e implantações pequenas. Separe os papéis em dois implantáveis quando a geração de relatórios precisa escalar por conta própria: renderizar um PDF grande custa muito mais do que aceitar a requisição que o pediu, e implantações separadas deixam você dimensionar cada lado conforme a carga dele.

## O caminho que um relatório percorre

***

<Steps>
  <Step title="A API aceita a requisição">
    Um `POST` para `/v1/reports` nomeia um template e os filtros dele. O Reporter toma primeiro uma trava de idempotência, chaveada no cabeçalho `X-Idempotency` quando você o envia e em um hash do corpo da requisição quando não envia. Uma duplicata ainda em andamento é recusada; uma duplicata de uma requisição concluída repete o relatório original e marca a resposta como repetição.
  </Step>

  <Step title="A API valida e persiste">
    O Reporter carrega o mapa de campos e o formato de saída do template, confere os campos de filtro contra o esquema ao vivo de cada fonte de dados e grava o relatório com status `Processing`.
  </Step>

  <Step title="A API enfileira o trabalho">
    Ela publica uma mensagem de comando na fila interna do RabbitMQ e responde `201 Created` com o relatório em `Processing`. Quem chamou termina aqui. A renderização ainda não começou.
  </Step>

  <Step title="O worker renderiza">
    O worker consome o comando, pula se o relatório já ficou em `Finished` ou `Error`, carrega o template do object storage, extrai os dados de cada fonte de dados, renderiza o documento, o converte para PDF quando o formato exige e sobe o artefato.
  </Step>

  <Step title="O worker acomoda o estado">
    Ele grava `Finished`, `Partial` ou `Error` e emite o evento correspondente. A operação de download serve o artefato quando o relatório está em `Finished`.
  </Step>
</Steps>

## A fila entre elas

***

A API e o worker se comunicam por uma fila do RabbitMQ que carrega comandos de relatório em uma única direção, com uma fila de mensagens mortas atrás dela. Essa fila é encanamento privado entre as duas superfícies do mesmo binário. Ela não é um ponto de integração, não carrega nenhum contrato sobre o qual você deva construir, e o exchange, a fila e a routing key dela são todos configurados pelo operador.

Eventos de negócio são um canal separado. O Reporter os publica em um exchange próprio, que o operador configura e que o valor de referência da implantação nomeia `reporter.events`. Toda emissão acontece depois do commit no banco de dados e nunca faz o trabalho que a produziu falhar. Eventos de alto valor passam por um outbox durável em vez de uma publicação direta, então uma indisponibilidade do broker os atrasa em vez de perdê-los.

## Extração de dados

***

O worker não fala com os seus bancos de dados por consultas escritas à mão. Ele roda o mesmo motor de extração que move o [Fetcher](/pt/fetcher/fetcher-core-concepts), embarcado no processo, sem nenhum salto de rede para um serviço separado.

O motor delimita toda execução. Os padrões permitem 10 fontes de dados por relatório, 50 tabelas por fonte de dados, 200 campos por tabela, quatro fontes de dados extraídas em paralelo e um prazo de cinco minutos para a extração inteira. As falhas são acumuladas em vez de fatais: um relatório cujas seções têm sucesso em parte renderiza com o que tem e se acomoda como `Partial`, registrando quais seções falharam.

## Armazenamentos e artefatos

***

| Dependência                      | Papel                                                                           |
| -------------------------------- | ------------------------------------------------------------------------------- |
| MongoDB                          | Templates, relatórios, prazos e o outbox de eventos.                            |
| RabbitMQ                         | A fila interna de relatórios e o exchange de eventos de negócio.                |
| Redis ou Valkey                  | Travas de idempotência, o cache de esquema e sinais de ciclo de vida de tenant. |
| Object storage compatível com S3 | Os arquivos de template e os artefatos renderizados, em um único bucket.        |

O object storage é compatível com S3: o Reporter fala o protocolo S3 e qualquer serviço que o responda funciona como destino. As fontes de template pousam sob o prefixo `templates/`, e os artefatos renderizados sob `reports/`, com os identificadores de template e de relatório e o formato de saída como extensão. O Reporter não aplica nenhuma expiração própria, então a retenção é uma política de ciclo de vida que você define no bucket.

## O Reporter e o Midaz

***

O Midaz é uma **fonte de dados** para o Reporter, não uma dependência de execução. O Reporter não carrega código específico do Midaz: um banco de dados do Midaz é registrado com as mesmas variáveis `DATASOURCE_*` de qualquer outro banco PostgreSQL, e os templates o endereçam pelo `configName` que o operador escolheu.

Duas consequências vêm daí. O Reporter sobe e atende templates, prazos e métricas sem nenhuma fonte de dados configurada, então uma indisponibilidade do Midaz nunca impede o Reporter de rodar. E a mesma implantação pode reportar sobre o Midaz, sobre os seus próprios bancos de dados e sobre os dois em um único template.

Aponte o Reporter para uma réplica de leitura onde houver uma. O caminho de extração só lê, mas a carga de consulta de um relatório pesado é real, e uma réplica a mantém fora do caminho de escrita do ledger.

<Note>
  Veja [Conectar o Reporter ao Midaz](/pt/reporter/connecting-reporter-to-midaz) para as variáveis, a convenção de `configName` e como confirmar que a fonte está visível.
</Note>

## Saúde e prontidão

***

As duas superfícies expõem `/health` e `/readyz` antes da autenticação, então as sondas chegam sem token. O `/health` responde 503 até a autoverificação de inicialização ter sucesso, o que permite a um orquestrador reiniciar um pod que não conseguiu alcançar as dependências dele no boot. O `/readyz` reporta as dependências que aquela superfície realmente usa, e a resposta dele informa em qual modo de implantação o processo está rodando. A superfície de API também serve `/version` com a procedência do build.

Leia a [referência de saúde e prontidão](/pt/reference/health-and-readiness) para o contrato de sondas compartilhado pelos produtos Lerian.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Conceitos centrais" icon="cubes" href="/pt/reporter/reporter-core-concepts">
    Templates, fontes de dados, relatórios, prazos e os quatro estados de um relatório.
  </Card>

  <Card title="Variáveis de ambiente" icon="gear" href="/pt/reporter/reporter-environment-variables">
    Cada ajuste que molda uma implantação do Reporter.
  </Card>
</CardGroup>
