> ## 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 da API, a superfície do worker, ou ambas, a fila entre elas, e os armazenamentos que compartilham.

O Reporter é entregue como **um binário**. `RUN_MODE` seleciona quais superfícies esse binário serve: `api`, `worker`, ou `all`. A API e o worker são dois papéis do mesmo programa, não dois produtos. Eles compartilham um build, uma versão, e um release.

Você escolhe uma topologia no momento do deploy, definindo uma variável de ambiente.

## Duas superfícies, um binário

***

| Superfície | `RUN_MODE` | Serve                                                                                                                               |
| ---------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| API        | `api`      | Toda operação REST na porta `4005`, além de `/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`      | Ambas as superfícies em um único processo.                                                                                          |

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

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

Execute `all` quando um processo é suficiente, o que é a escolha usual para desenvolvimento local e deployments pequenos. Divida os papéis em dois deployables quando a geração de relatórios precisar escalar por conta própria. Renderizar um PDF grande custa muito mais do que aceitar a requisição que o pediu. Deployments separados permitem dimensionar cada lado para a própria carga.

## 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 obtém um lock de idempotência primeiro. A chave do lock é o header `X-Idempotency` quando você envia um, e um hash do corpo da requisição quando você não envia. O Reporter rejeita uma duplicata que ainda está em andamento. Uma duplicata de uma requisição concluída repete o relatório original e marca a resposta como uma 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. Em seguida, ele verifica os campos de filtro contra o schema ativo 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 `Processing`. Quem chamou não precisa fazer mais nada. A renderização ainda não começou.
  </Step>

  <Step title="O worker renderiza">
    O worker consome o comando. Ele pula o comando se o relatório já se consolidou como `Finished` ou `Error`. Ele carrega o template do armazenamento de objetos e extrai os dados de cada fonte de dados. Ele renderiza o documento e o converte para PDF quando o formato exige. Ele envia o artefato.
  </Step>

  <Step title="O worker consolida o estado">
    Ele grava `Finished`, `Partial`, ou `Error` e emite o evento correspondente. A operação de download entrega o artefato assim que o relatório está `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 direção, com uma dead-letter queue atrás dela. Essa fila funciona como infraestrutura interna 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ê deveria construir, e a exchange, a fila, e a routing key dela são todas configuradas pelo operador.

Eventos de negócio são um canal separado. O Reporter os publica na própria exchange deles, que o operador configura e que o valor de referência do deployment nomeia como `reporter.events`. Toda emissão acontece depois do commit no banco de dados e nunca falha o trabalho que a produziu. 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 conversa com os seus bancos de dados por meio de consultas escritas à mão. Ele executa o motor de extração embarcado dele, sem um salto de rede para um serviço separado.

O motor limita cada execução. Os padrões permitem 10 fontes de dados por relatório, 50 tabelas por fonte de dados, e 200 campos por tabela. Eles também permitem quatro fontes de dados extraídas em paralelo, e um prazo de cinco minutos para a extração inteira. Falhas não encerram a execução. Um relatório cujas seções têm sucesso parcial renderiza a partir do que tem. Ele se consolida como `Partial` e registra 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 a exchange de eventos de negócio.                  |
| Redis ou Valkey                            | Locks de idempotência, o cache de schema, e os sinais de ciclo de vida do tenant. |
| Armazenamento de objetos compatível com S3 | Arquivos de template e artefatos renderizados, em um único bucket.                |

O armazenamento de objetos é compatível com S3: o Reporter fala o protocolo S3 e qualquer serviço que o responda funciona como destino. As fontes de template chegam sob o prefixo `templates/`, e os artefatos renderizados sob `reports/`, indexados pelo identificador do template e do relatório com 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.

## Reporter e Midaz

***

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

Duas consequências decorrem disso. O Reporter inicia e serve templates, prazos, e métricas sem nenhuma fonte de dados configurada, então uma indisponibilidade do Midaz nunca impede o Reporter de rodar. E o mesmo deployment pode gerar relatórios sobre o Midaz, sobre os seus próprios bancos de dados, e sobre ambos em um único template.

Aponte o Reporter para uma read replica onde uma existir. O caminho de extração apenas lê, mas a carga de consultas de um relatório pesado é real, e uma replica mantém essa carga fora do caminho de escrita do ledger.

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

## Saúde e readiness

***

Ambas as superfícies expõem `/health` e `/readyz` antes da autenticação, para que os probes as alcancem sem um token. O probe `/health` responde 503 até que a auto-verificação de inicialização seja bem-sucedida. Isso permite que um orquestrador reinicie um pod que não conseguiu alcançar suas dependências na inicialização. O probe `/readyz` reporta as dependências que essa superfície realmente usa, e a resposta dele indica em qual modo de deployment o processo está rodando. A superfície da API também serve `/version` com a proveniência do build.

Leia a [referência de saúde e readiness](/pt/reference/health-and-readiness) para o contrato de probe compartilhado entre os produtos Lerian.

## Próximos passos

***

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

  <Card title="Variáveis de ambiente" icon="gear" href="/pt/products/reporter/reporter-environment-variables">
    Toda configuração que molda um deployment do Reporter.
  </Card>
</CardGroup>
