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

# Eventos do Reporter

> Inscreva-se nos eventos de relatório e prazo do Reporter: a operação de manifesto de streaming, o envelope CloudEvents, as políticas de entrega e o que cada payload carrega.

O Reporter publica um evento de negócio sempre que um template, um relatório ou um prazo muda de estado. Inscreva-se nesses eventos e você saberá que um relatório terminou, sem precisar consultar `GET /v1/reports/{id}`.

`GET /v1/streaming/events` descreve o contrato em formato legível por máquina. Esta página cobre o lado do consumidor: o que o manifesto informa, o que chega pela rede e o que cada evento carrega.

## A operação de manifesto

***

[Eventos de streaming](/pt/reference/products/reporter/get-streaming-events) retorna o catálogo estático de eventos. Essa operação exige autenticação como qualquer outra. Ela responde com `Cache-Control: no-store` e responde independentemente de este deploy publicar eventos ou não. Leia-a na inicialização para conferir se o seu consumidor e o Reporter concordam quanto ao contrato.

A resposta expõe a identidade da aplicação e o catálogo:

| Campo       | O que ele carrega                                                                                                                                                                                           |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `version`   | Versão semântica do formato de transporte do manifesto.                                                                                                                                                     |
| `publisher` | Quem publica: `serviceName` e `source` são `reporter`, `routePath` é esta operação, e `outboxSupported` é `true`, além das versões da aplicação e da biblioteca.                                            |
| `events`    | Uma entrada por definição de evento, com sua chave, `eventKey`, tipo de recurso, tipo de evento, `class`, versão do schema, descrição e política de entrega padrão. O Reporter emite apenas eventos `fact`. |
| `routes`    | Omitido. O Reporter não publica a topologia do broker pela API.                                                                                                                                             |

## Roteamento no broker

***

O manifesto não revela um tópico nem a topologia do broker. Vincule sua fila ao exchange nomeado por `RABBITMQ_REPORT_EVENTS_EXCHANGE`. Cada mensagem usa a chave da definição de evento ao pé da letra como sua routing key AMQP: `report.finished`, `deadline.delivery_reverted`, incluindo os sublinhados.

## O catálogo de eventos

***

Existem doze definições de evento nos dois modos de execução.

| Evento                       | Emitido quando                                                        | Perfil de entrega |
| ---------------------------- | --------------------------------------------------------------------- | ----------------- |
| `template.created`           | Um template é enviado.                                                | Importante        |
| `template.updated`           | O arquivo ou os metadados de um template mudam.                       | Importante        |
| `template.deleted`           | Um template é removido, com a contagem de prazos afetados em cascata. | Importante        |
| `report.requested`           | Uma solicitação de relatório é aceita e entra na fila.                | Importante        |
| `report.finished`            | Toda seção de dados é bem-sucedida e o artefato é armazenado.         | Crítico           |
| `report.partial`             | Algumas seções falham. Um artefato existe.                            | Crítico           |
| `report.errored`             | O relatório termina em erro.                                          | Crítico           |
| `deadline.created`           | Um prazo é criado.                                                    | Importante        |
| `deadline.updated`           | Um prazo muda.                                                        | Importante        |
| `deadline.deleted`           | Um prazo é removido.                                                  | Importante        |
| `deadline.delivered`         | Um prazo é marcado como entregue.                                     | Crítico           |
| `deadline.delivery_reverted` | Uma marca de entrega é revertida.                                     | Crítico           |

Esse canal é apenas para publicação. O Reporter emite esses eventos e não consome nenhum deles.

## Entrega

***

Todo evento do manifesto tem a classe `fact`. O perfil de entrega na tabela acima seleciona sua política de entrega.

| Perfil de entrega | Publicação direta | Outbox                                   | DLQ da rota     |
| ----------------- | ----------------- | ---------------------------------------- | --------------- |
| Importante        | Sim               | Recorre ao outbox quando o circuito abre | Não configurado |
| Crítico           | Não               | Sempre                                   | Não configurado |

Por isso, um evento com o perfil de entrega `Critical` nunca publica diretamente no broker. O Reporter grava o evento no outbox de streaming durável do Mongo depois do commit do estado de negócio, e um dispatcher o reproduz depois de uma interrupção do broker.

A gravação do estado e a inserção no outbox são operações separadas, não uma única transação atômica da aplicação. Essa lacuna é uma janela de falha: uma queda ou uma inserção com falha no outbox depois do commit do estado perde o evento. Nenhuma conciliação o recupera. A perda deixa apenas um log de erro e uma métrica. Depois que a linha está no outbox, o dispatcher faz novas tentativas até a entrega.

A política solicita tratamento de dead-letter para falhas roteáveis, mas as rotas atuais do RabbitMQ não fornecem um destino DLQ explícito. Essa falha é exposta e registrada em log, sem cópia forense em dead-letter.

A emissão acontece depois do commit e nunca faz o trabalho falhar. Um problema de publicação não transforma um relatório armazenado em um relatório com erro.

<Warning>
  A entrega é pelo menos uma vez. Faça a deduplicação por `(ce-source, ce-id)`. Apenas os fatos terminais de relatório (`report.finished`, `report.partial` e `report.errored`) e as transições críticas de prazo (`deadline.delivered` e `deadline.delivery_reverted`) usam identificadores determinísticos. Os eventos de template, `report.requested` e os eventos de criação/atualização/exclusão de prazo deixam o identificador a cargo do `lib-streaming`.
</Warning>

## O envelope CloudEvents

***

As mensagens trafegam no modo binário do CloudEvents, versão 1.0. Os atributos de contexto viajam como headers da mensagem.

| Header             | Valor                                                                                             |
| ------------------ | ------------------------------------------------------------------------------------------------- |
| `ce-specversion`   | `1.0`                                                                                             |
| `ce-id`            | Id opaco definido pelo produtor; determinístico apenas para as classes de evento descritas acima  |
| `ce-source`        | `reporter`                                                                                        |
| `ce-type`          | `studio.lerian.reporter.<resource>.<event>`, por exemplo `studio.lerian.reporter.report.finished` |
| `ce-time`          | Timestamp de emissão em RFC 3339                                                                  |
| `ce-subject`       | O identificador do relatório, template ou prazo                                                   |
| `ce-resourcetype`  | `report`, `template` ou `deadline`                                                                |
| `ce-eventtype`     | `finished`, `created`, `delivery_reverted`, entre outros                                          |
| `ce-schemaversion` | `1.0.0`                                                                                           |
| `ce-tenantid`      | O tenant dono da mudança                                                                          |

O Reporter marca as mensagens como persistentes. Um deploy single-tenant também registra um valor de tenant, então um único consumidor lida com os dois formatos de deploy com o mesmo código.

## O que um payload carrega

***

As chaves do payload são em `snake_case`, diferente da superfície REST em camelCase. Um corpo de `report.finished`:

```json theme={null}
{
  "report_id": "019826f4-6a9c-7b31-9d40-2f1e8c5a4b77",
  "template_id": "8f2c1a9e-4b30-4c02-9a1b-2d5e6f7a1c33",
  "output_format": "pdf",
  "status": "Finished",
  "artifact_object_key": "org-01abc/reports/8f2c1a9e-4b30-4c02-9a1b-2d5e6f7a1c33/019826f4-6a9c-7b31-9d40-2f1e8c5a4b77.pdf",
  "artifact_content_type": "application/pdf",
  "completed_at": "2026-07-29T14:22:08Z",
  "duration_ms": 8421,
  "section_count": 3
}
```

`artifact_object_key` é a chave exata do objeto informada pelo storage depois da gravação, não um caminho que se recomenda que os consumidores reconstruam. No modo single-tenant, ela tem a forma `reports/<templateId>/<reportId>.<format>`. O modo multi-tenant prefixa o mesmo caminho com o segmento do tenant. Use o valor ao pé da letra.

Se você validar o segmento de tenant, compare-o com o tenant vinculado à sua subscription autenticada, não com outro campo da mesma mensagem. Uma chave vazia em `report.finished` ou `report.partial` é uma violação de contrato. [Baixar um relatório](/pt/reference/products/reporter/download-report) continua sendo a forma aceita para buscar um relatório no estado `Finished`.

`report.partial` adiciona `section_failures` e `failed_section_count` junto com os mesmos campos de artefato. Uma chave resolvível não significa que o relatório está completo. Encaminhe a entrega regulatória apenas a partir de `report.finished`, e decodifique estritamente o campo `status` em vez de usar a presença da chave como discriminador.

`report.errored` substitui os campos de artefato por `error_code` e `error_summary`. A ausência de um campo de artefato não prova que nenhum objeto foi gravado: o storage pode ter sucesso antes que a persistência do status terminal falhe, deixando um objeto que nenhum evento nomeia. Os dois campos de erro vêm de um vocabulário fixo: `report_generation_failed`, `report_generation_timeout` ou `report_generation_canceled`. Cada código tem um resumo fixo. O texto bruto do erro nunca trafega na rede, então um payload não pode vazar uma query, uma connection string ou dados de tenant. Ramifique a lógica com base em `error_code`.

## Habilitando a publicação de eventos

***

A publicação de eventos é uma escolha de deploy, definida com `STREAMING_ENABLED`. Ao ativá-la, o Reporter exige mais três configurações na inicialização:

| Configuração                      | Valor                                                                                                    |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `RABBITMQ_REPORT_EVENTS_EXCHANGE` | O exchange que carrega os eventos. Configurado pelo operador; o valor de referência é `reporter.events`. |
| `STREAMING_BROKERS`               | Deve estar presente e não vazio.                                                                         |
| `STREAMING_CLOUDEVENTS_SOURCE`    | Deve ser exatamente `reporter`; a inicialização rejeita qualquer outro valor.                            |

Quando a publicação está desativada, `STREAMING_CLOUDEVENTS_SOURCE` pode ficar sem valor definido. Se estiver definida, ainda deve ser exatamente `reporter`. O Reporter rejeita qualquer outro valor não vazio na inicialização, mesmo com a publicação desativada. Quando a publicação está ativada, o Reporter também se recusa a iniciar se qualquer uma das três configurações estiver em branco, então um deploy malconfigurado falha na inicialização em vez de descartar eventos silenciosamente.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Reporter REST API" icon="code" href="/pt/products/reporter/reporter-rest-api">
    As 28 operações, autenticação, paginação e erros.
  </Card>

  <Card title="Referência da API" icon="list" href="/pt/reference/introduction">
    A operação de manifesto de streaming, com seu formato de resposta completo.
  </Card>

  <Card title="Variáveis de ambiente" icon="gear" href="/pt/products/reporter/reporter-environment-variables">
    Todas as configurações por trás das superfícies de streaming, exchange e modo de execução.
  </Card>

  <Card title="O que é o Reporter?" icon="book" href="/pt/products/reporter/what-is-reporter">
    Templates, relatórios, prazos e onde eles se encaixam.
  </Card>
</CardGroup>
