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
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
1
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.2
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.3
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.4
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.5
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.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, 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
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.
Veja Conectar o Reporter ao Midaz para as variáveis, a convenção de
configName e como confirmar que a fonte está visível.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 para o contrato de sondas compartilhado pelos produtos Lerian.
Próximos passos
Conceitos centrais
Templates, fontes de dados, relatórios, prazos e os quatro estados de um relatório.
Variáveis de ambiente
Cada ajuste que molda uma implantação do Reporter.

