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

# Implantação do Reporter

> Implante o Reporter: um binário com seletor de modo de execução, MongoDB, a fila de comandos de relatório, object storage compatível com S3, Redis ou Valkey, dimensionamento do worker e retenção de relatórios por política de ciclo de vida do bucket.

O Reporter é entregue como um binário único com duas superfícies. O `RUN_MODE` seleciona quais superfícies um processo atende, então a mesma imagem roda como a API, como o worker de relatórios, ou como os dois. Quatro dependências ficam atrás delas.

O Reporter lê os seus bancos de dados por um motor de extração que roda dentro do processo worker. Não há um serviço de extração separado para implantar.

## O que você implanta

***

| Componente               | Papel                                                                                       | Escala por                      |
| ------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------- |
| **Superfície de API**    | API REST de templates, relatórios, prazos e fontes de dados. Publica comandos de relatório. | Taxa de requisições.            |
| **Worker de relatórios** | Consumidor de fila. Extrai os dados, renderiza o relatório e grava o artefato.              | Profundidade da fila.           |
| **MongoDB**              | Templates, relatórios, prazos e o outbox durável de eventos.                                | Volume de metadados.            |
| **RabbitMQ**             | A fila de comandos de relatório, e o exchange de eventos de negócio.                        | Taxa de relatórios.             |
| **Object storage**       | Fontes de template e relatórios renderizados. Compatível com S3.                            | Volume de artefatos e retenção. |
| **Redis ou Valkey**      | Travas de idempotência, cache de esquemas e ciclo de vida de tenants.                       | As duas superfícies.            |

## Modos de execução

***

O `RUN_MODE=api` atende todas as operações REST, mais `/health`, `/readyz` e `/version`, no endereço definido em `SERVER_ADDRESS`. O `RUN_MODE=worker` consome a fila de comandos de relatório e atende `/health` e `/readyz` na `HEALTH_PORT`. O `RUN_MODE=all` roda as duas superfícies em um só processo.

Use `all` para desenvolvimento local. Em produção, implante as duas superfícies em separado, para a geração de relatórios escalar por conta própria.

```bash theme={null}
# Implantação de API
RUN_MODE=api
SERVER_ADDRESS=:4005

# Implantação de worker
RUN_MODE=worker
HEALTH_PORT=4006
```

## MongoDB

***

As duas superfícies usam a mesma implantação de MongoDB. A superfície de API grava templates, relatórios e prazos; o worker atualiza um relatório à medida que o conclui.

Em modo single-tenant, `MONGO_HOST` e `MONGO_NAME` são obrigatórias na inicialização. Em modo multi-tenant, cada tenant recebe o próprio banco, resolvido a partir do JWT da requisição. Esse caminho falha de forma fechada: uma requisição que carrega um tenant sem banco de tenant retorna um erro em vez de tocar um banco compartilhado.

## RabbitMQ

***

Dois assuntos distintos dividem um mesmo broker.

### A fila de comandos de relatório

Essa fila leva o trabalho da superfície de API até o worker. `RABBITMQ_EXCHANGE`, `RABBITMQ_GENERATE_REPORT_QUEUE` e `RABBITMQ_GENERATE_REPORT_KEY` nomeiam o exchange, a fila e a routing key. A superfície de API publica, então precisa das três. O worker só consome, então precisa de `RABBITMQ_GENERATE_REPORT_QUEUE` sozinha. As duas superfícies precisam da conexão com o broker em si, e os objetos precisam existir antes de os serviços subirem.

O canal é interno do Reporter. Para saber que um relatório terminou, assine os eventos de negócio abaixo, ou consulte o relatório.

Um worker que falha uma mensagem tenta de novo até cinco vezes com backoff, e depois a rejeita sem reenfileirar. Ligue um dead-letter exchange à fila de comandos, para um relatório rejeitado cair em um lugar que você possa inspecionar.

### O exchange de eventos

Os eventos de negócio (`template.*`, `report.*`, `deadline.*`) vão para um exchange que você nomeia em `RABBITMQ_REPORT_EVENTS_EXCHANGE`. O valor é definido pelo operador; `reporter.events` é o valor de referência.

Defina esse exchange, `STREAMING_BROKERS` e `STREAMING_CLOUDEVENTS_SOURCE` sempre que `STREAMING_ENABLED=true`. Com o streaming desligado, as duas superfícies sobem normalmente e não publicam nada.

## Object storage

***

O Reporter usa um único bucket compatível com S3, nomeado em `OBJECT_STORAGE_BUCKET`. Ele guarda dois tipos de objeto, cada um sob o seu próprio prefixo:

* a fonte do template, como `templates/<templateId>.tpl`
* o relatório renderizado, como `reports/<templateId>/<reportId>.<format>`

Em modo multi-tenant, os dois prefixos ficam sob o tenant dono do objeto: `<tenantId>/templates/...` e `<tenantId>/reports/...`.

AWS S3, MinIO e SeaweedFS funcionam. Alcance o SeaweedFS pelo gateway S3 dele. `OBJECT_STORAGE_USE_PATH_STYLE=true` é o que MinIO e SeaweedFS esperam, e `OBJECT_STORAGE_DISABLE_SSL` fica em `false` fora do desenvolvimento local.

### Retenção de relatórios

O Reporter guarda todo relatório que renderiza, então o bucket cresce com o seu volume de relatórios. Defina a expiração no bucket, com a política de ciclo de vida do próprio object storage, sobre a janela que as suas regras de retenção exigem.

<Warning>
  **Ancore a regra no prefixo de relatórios que o seu modo de tenancy produz.** Em modo single-tenant, toda chave de relatório começa em `reports/`, então uma regra sobre esse prefixo cobre o bucket. Em modo multi-tenant, a chave carrega o tenant à frente, então a regra precisa do prefixo completo `<tenantId>/reports/`, uma regra por tenant. Deixe `templates/` fora do alcance nos dois casos: uma regra que cobre o bucket inteiro também remove os templates a partir dos quais os seus relatórios são renderizados.
</Warning>

## Redis ou Valkey

***

`REDIS_HOST` é obrigatória na superfície de API. No worker ela só é obrigatória quando `MULTI_TENANT_ENABLED=true`, onde faz cache da descoberta de tenants. O Redis sustenta a trava de idempotência na criação de relatórios, o cache de esquemas das fontes de dados e as mensagens de ciclo de vida de tenants em modo multi-tenant.

O estado de idempotência vive no Redis, e não na memória do processo, então as réplicas de API o compartilham. A mesma requisição de relatório enviada duas vezes, para duas réplicas, cria um relatório só.

## Fontes de dados

***

O Reporter lê os dados dos relatórios de fontes de dados PostgreSQL e MongoDB declaradas no ambiente, um bloco `DATASOURCE_{NAME}_*` por fonte. Veja [Variáveis de ambiente](/pt/reporter/reporter-environment-variables) para o bloco.

Não existe uma API que registre uma fonte de dados, então uma fonte nova é uma mudança de configuração e um reinício. O Reporter também sobe sem nenhuma configurada, e atende templates, prazos e métricas.

## Dimensionar o worker

***

`RABBITMQ_NUMBERS_OF_WORKERS` define quantos trabalhos de relatório um processo worker roda em paralelo. Para escala horizontal, adicione réplicas do worker e comande-as pela profundidade da fila de comandos.

A saída em PDF é renderizada por um pool de navegador headless: `PDF_POOL_WORKERS` renderizações concorrentes, com padrão 2, cada uma limitada por `PDF_TIMEOUT_SECONDS`, com padrão 90. Dimensione a memória do worker contra esse pool, e não apenas contra as linhas que um relatório lê. Os demais formatos de saída não o usam.

Todo relatório carrega também limites fixos de extração. Eles são 10 fontes de dados, 50 tabelas por fonte de dados e 200 campos por tabela, com 4 fontes de dados lidas por vez, um prazo de 300 segundos e um teto de 100 MiB de dados extraídos. As variáveis `ENGINE_*` mudam esses valores.

## Modo de implantação e TLS

***

O `DEPLOYMENT_MODE` declara o sabor da implantação: `local`, `byoc` ou `saas`. Ele etiqueta a resposta de `/readyz` e, em `saas`, exige TLS.

<Warning>
  **O modo SaaS exige TLS em toda dependência.** Defina `DEPLOYMENT_MODE=saas` e uma URL em texto claro de MongoDB, RabbitMQ, Redis, object storage ou Tenant Manager interrompe o processo. A parada ocorre antes de qualquer conexão abrir.
</Warning>

Deixe `ALLOW_INSECURE_TLS` sem definir em produção. Ela ignora essas checagens, e a stack de desenvolvimento local é o único lugar para ela.

## Checagens de inicialização

***

O Reporter valida a configuração antes de atender qualquer coisa. Cada checagem abaixo interrompe o processo, e o erro nomeia todas as variáveis em falta.

| Gatilho                                                                                                                                                                  | O que o operador vê                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------- |
| `SERVER_ADDRESS`, `REDIS_HOST` ou qualquer uma das três variáveis da fila de comandos ausente na superfície de API                                                       | A validação de configuração falha e lista cada variável ausente.                  |
| `RABBITMQ_GENERATE_REPORT_QUEUE` ausente na superfície de worker                                                                                                         | A validação de configuração falha e a nomeia.                                     |
| `MONGO_HOST` ou `MONGO_NAME` ausente, em modo single-tenant                                                                                                              | A validação de configuração nomeia as duas.                                       |
| `MULTI_TENANT_ENABLED=true` sem `MULTI_TENANT_URL` ou `MULTI_TENANT_SERVICE_API_KEY`                                                                                     | A validação de configuração nomeia a variável que o runtime de tenants precisa.   |
| `STREAMING_ENABLED=true` sem `RABBITMQ_REPORT_EVENTS_EXCHANGE`, `STREAMING_BROKERS` e `STREAMING_CLOUDEVENTS_SOURCE` — as três são obrigatórias para subir com streaming | A inicialização aborta em vez de rodar com eventos que não chegam a lugar nenhum. |
| `DEPLOYMENT_MODE=saas` com uma URL de dependência em texto claro                                                                                                         | A inicialização aborta antes de qualquer conexão abrir.                           |

<Note>
  **Uma dependência fora do ar no boot não produz um pod quebrado em silêncio.** O `/health` retorna 503 até a autossondagem de inicialização passar. O kubelet então reinicia o pod, em vez de mandar tráfego para ele.
</Note>

## Atualizações contínuas

***

Em `SIGTERM`, as duas superfícies entram em drenagem. O `/readyz` responde 503 desde o momento em que o sinal chega, antes de os servidores começarem o desligamento, e as requisições e mensagens em voo terminam. O Kubernetes remove o pod dos endpoints do Service enquanto ele ainda funciona.

Defina o período de graça de término acima da sua renderização de relatório mais longa. Veja a [referência de saúde e prontidão](/pt/reference/health-and-readiness) para o que as sondas reportam durante uma drenagem.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Variáveis de ambiente" icon="gear" href="/pt/reporter/reporter-environment-variables">
    Cada variável do Reporter, por categoria.
  </Card>

  <Card title="Configuração BYOC" icon="sliders" href="/pt/reference/byoc-configuration">
    Os blocos de configuração que todo produto Lerian compartilha.
  </Card>

  <Card title="Saúde e prontidão" icon="heart-pulse" href="/pt/reference/health-and-readiness">
    O contrato das sondas e o que cada resposta significa.
  </Card>

  <Card title="Conectar o Reporter ao Midaz" icon="link" href="/pt/reporter/connecting-reporter-to-midaz">
    Aponte o Reporter para um banco do Midaz e renderize seu primeiro relatório.
  </Card>
</CardGroup>
