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

> Consulte os CloudEvents emitidos pelo Lerian Reporter: as 17 definições de evento, seus contratos de payload e versões de schema, as rotas do RabbitMQ, a cópia no Kafka e as políticas de entrega.

O Reporter tem **17 definições de eventos de negócio emitidos**. São mensagens **CloudEvents 1.0** no modo binário. Todo evento trafega pelo RabbitMQ quando `STREAMING_ENABLED=true`. Quando `STREAMING_KAFKA_BROKERS` também está definido, o worker publica `report.finished` e `report.partial` também no Kafka. Quando o streaming está desligado, o Reporter não publica eventos.

## Envelope e roteamento

Todo evento usa `ce-source` `reporter` e um `ce-type` qualificado pela fonte no formato `studio.lerian.reporter.<resource>.<event>`. O payload é JSON com chaves em `snake_case`.

| Item do contrato | Valor |
| - | - |
| Exchange | Valor de `RABBITMQ_REPORT_EVENTS_EXCHANGE` |
| Chave de roteamento AMQP | Exatamente a chave de definição, como `report.finished` |
| Tópico Kafka | `lerian.streaming.reporter`, apenas para `report.finished` e `report.partial`, quando `STREAMING_KAFKA_BROKERS` está definido |
| Tipo de conteúdo | `application/json` |
| Modo de entrega | Mensagem AMQP persistente |
| Tipo de recurso | `template`, `report`, `deadline` ou `regulatory` |
| Subject | ID de template, relatório ou prazo. Em `regulatory.version_adopted`, o ID do documento regulatório |
| Tenant | Tenant do contexto em `ce-tenantid` e `X-Tenant-ID`; `default` no modo single-tenant |
| Manifesto | [`GET /v1/streaming/events`](https://docs.lerian.studio/pt/reference/products/reporter/get-streaming-events) |

As duas cópias carregam o mesmo `ce-id`.

Use o [envelope compartilhado](https://docs.lerian.studio/pt/reference/events/overview.md) para o contrato completo de header do CloudEvents.

## Semântica de entrega

O Reporter emite o evento depois que a mudança de estado de negócio recebe commit. Erros de publicação não falham a operação subjacente.

* **Importante:** publicação direta, com fallback de outbox durável quando o circuito do broker está aberto.
* **Crítico:** o Reporter pula a publicação direta. Ele sempre persiste o evento no outbox durável para despacho e nova tentativa.
* As duas políticas solicitam `on_routable_failure`, mas as rotas não definem um destino DLQ explícito. O publicador vê uma falha roteável. Nenhuma cópia vai para uma rota dead-letter.
* A entrega do broker é pelo menos uma vez. Os consumidores devem ser idempotentes e fazer deduplicação com `(ce-source, ce-id)`.

## Catálogo de eventos emitidos

| Chave de definição | Emitido por | Política | Schema | Disparado quando |
| - | - | - | - | - |
| `template.created` | Manager | Importante | `1.0.0` | O arquivo do template e os metadados são persistidos. |
| `template.updated` | Manager | Importante | `1.0.0` | Uma atualização do template e qualquer substituição de arquivo são concluídas, ou uma atribuição de família de relatório muda a categoria do template. |
| `template.deleted` | Manager | Importante | `1.0.0` | Uma exclusão de template é concluída; o rollback de criação não o emite. |
| `report.requested` | Manager | Importante | `1.0.0` | Um relatório criado por `POST /v1/reports` ou pelo gatilho de prazos é persistido como `Processing`, antes de o manager publicar o comando do worker. Isso não comprova que o comando foi enfileirado. Uma requisição de remessa regulatória não o emite. |
| `report.finished` | Worker | Crítico | `2.0.0` | O artefato é armazenado e o status `Finished` recebe commit. |
| `report.partial` | Worker | Crítico | `2.0.0` | O artefato é armazenado e o status `Partial` recebe commit. |
| `report.errored` | Manager e worker | Crítico | `2.0.0` | Um status `Error` recebe commit: a execução do worker falhou, o manager não conseguiu enfileirar o comando de um relatório criado por `POST /v1/reports` ou pelo gatilho de prazos, ou o manager detectou que o worker parou de enviar heartbeats. |
| `deadline.created` | Manager | Importante | `1.0.0` | Um prazo é persistido. |
| `deadline.updated` | Manager | Importante | `1.0.0` | Uma atualização de prazo é persistida e o registro atualizado é carregado. |
| `deadline.deleted` | Manager | Importante | `1.0.0` | Um soft delete de prazo é persistido. |
| `deadline.delivered` | Manager | Crítico | `1.0.0` | A marca de entrega é persistida. |
| `deadline.delivery_reverted` | Manager | Crítico | `1.0.0` | A marca de entrega é removida. |
| `deadline.due` | Manager | Crítico | `1.0.0` | O gatilho de prazos anuncia uma ocorrência cujo dia chegou. Exige `DEADLINE_TRIGGER_ENABLED=true`. |
| `deadline.generation_failed` | Manager | Crítico | `1.0.0` | O gatilho anunciou uma ocorrência, e o relatório que ele precisava gerar para uma categoria de `DEADLINE_TRIGGER_GENERATE_CATEGORIES` foi recusado ou falhou. |
| `regulatory.draft_ready` | Worker | Crítico | `1.0.0` | Um rascunho regulatório e seu arquivo estão armazenados e prontos para revisão. `template_id` é uma string vazia quando uma inscrição gerou o rascunho. |
| `regulatory.filing_approved` | Manager | Crítico | `1.0.0` | Uma pessoa aprovou um rascunho regulatório, e ele está `Final`. Entregue a remessa a partir deste evento. |
| `regulatory.version_adopted` | Manager | Crítico | `1.0.0` | Uma inscrição passa para outra versão do seu documento regulatório. Adotar a versão já em vigor não emite nada. |

Uma remessa regulatória emite `regulatory.draft_ready` em vez de `report.finished`. Uma execução de remessa que falha emite `report.errored`.

## Identificadores de eventos

O Reporter define um `ce-id` determinístico nestes eventos:

| Evento | `ce-id` |
| - | - |
| `report.finished`, `report.partial` | `reporter.report.<status>.<report_id>`, com `finished` ou `partial` |
| `report.errored` | `reporter.report.error.<report_id>` |
| `deadline.delivered` | `reporter.deadline.delivered.<deadline_id>.<delivered_at>` |
| `deadline.delivery_reverted` | `reporter.deadline.delivery_reverted.<deadline_id>.<reverted_at>` |
| `deadline.due` | `reporter.deadline.due.<deadline_id>.<occurrence_at>` |
| `deadline.generation_failed` | `reporter.deadline.generation_failed.<deadline_id>.<occurrence_at>` |
| `regulatory.draft_ready` | `<report_id>:draft:1` |
| `regulatory.filing_approved` | `<report_id>:approved` |
| `regulatory.version_adopted` | `<document_id>:<adopted_version>:<tenant_id>` |

Todas as variantes de `report.errored` usam o mesmo `ce-id`. Por isso, um consumidor que faz deduplicação por `(ce-source, ce-id)` mantém apenas o primeiro `report.errored` recebido para um `report_id`. Os eventos de template, `report.requested` e os eventos de criação, atualização e exclusão de prazo carregam um identificador gerado.

## Contratos `data` completos

Estas declarações no estilo TypeScript refletem o formato do JSON na rede. `?` significa que a propriedade é opcional. `| null` significa que a propriedade está presente, mas pode ser `null` em JSON.

```typescript theme={null}
type RFC3339 = string
type UUID = string

type TemplateCreatedDataV1 = {
  template_id: UUID
  output_format: string
  description: string
  file_name: string
  category: string
  mapped_datasource_keys: string[]
  mapped_fields_count: number
  created_at: RFC3339
}

type TemplateUpdatedDataV1 = {
  template_id: UUID
  output_format: string
  description: string
  category: string
  updated_fields: string[]
  file_replaced: boolean
  updated_at: RFC3339
}

type TemplateDeletedDataV1 = {
  template_id: UUID
  hard_delete: boolean
  cascaded_deadlines_deleted: number
  deleted_at: RFC3339
}

type ReportRequestedDataV1 = {
  report_id: UUID
  template_id: UUID
  output_format: string
  status: string
  request_id: string
  filter_datasource_count: number
  template_description: string
}

type ReportFinishedDataV2 = {
  report_id: UUID
  template_id: UUID
  output_format: string
  status: string
  artifact_object_key: string
  artifact_content_type: string
  document_type: string
  artifact_ttl?: string
  completed_at: RFC3339
  duration_ms: number
  section_count: number
}

type ReportPartialDataV2 = {
  report_id: UUID
  template_id: UUID
  output_format: string
  status: string
  artifact_object_key: string
  artifact_content_type: string
  document_type: string
  section_failures: string[]
  completed_at: RFC3339
  duration_ms: number
  section_count: number
  failed_section_count: number
}

type ManagerReportErroredDataV2 = {
  report_id: UUID
  status: string
  error_code: "report_generation_failed" | "report_worker_lost"
  error_summary: string
  completed_at: RFC3339
}

type WorkerTerminalReportErroredDataV2 = {
  report_id: UUID
  template_id: UUID
  output_format: string
  status: string
  error_code: "report_generation_failed"
  error_summary: "All report data sections failed"
  document_type: string
  document_id: string
  document_version: string
  completed_at: RFC3339
  duration_ms?: number
}

type WorkerFunnelReportErroredDataV2 = {
  report_id: UUID
  status: string
  error_code:
    | "report_generation_failed"
    | "report_generation_timeout"
    | "report_generation_canceled"
  error_summary: string
  document_type: string
  document_id: string
  document_version: string
  completed_at: RFC3339
}

type ReportErroredDataV2 =
  | ManagerReportErroredDataV2
  | WorkerTerminalReportErroredDataV2
  | WorkerFunnelReportErroredDataV2

type DeadlineCreatedDataV1 = {
  deadline_id: UUID
  name: string
  type: string
  template_id: UUID | null
  template_name: string
  due_date: RFC3339
  frequency: string
  months_of_year: number[] | null
  active: boolean
  notify_days_before: number
  color: string
  status_snapshot: string
  created_at: RFC3339
}

type DeadlineUpdatedDataV1 = {
  deadline_id: UUID
  updated_fields: string[]
  template_id: UUID | null
  template_name: string
  due_date: RFC3339
  frequency: string
  months_of_year: number[] | null
  active: boolean
  status_snapshot: string
  updated_at: RFC3339
}

type DeadlineDeletedDataV1 = {
  deadline_id: UUID
  soft_delete: boolean
  deleted_at: RFC3339
}

type DeadlineDeliveredDataV1 = {
  deadline_id: UUID
  template_id: UUID | null
  template_name: string
  type: string
  due_date: RFC3339
  delivered_at: RFC3339 | null
  status_snapshot: string
  frequency: string
  next_occurrence: RFC3339 | null
  updated_at: RFC3339
}

type DeadlineDeliveryRevertedDataV1 = {
  deadline_id: UUID
  template_id: UUID | null
  template_name: string
  type: string
  due_date: RFC3339
  reverted_at: RFC3339
  previous_delivered_at: RFC3339 | null
  status_snapshot: string
  frequency: string
  updated_at: RFC3339
}

type DeadlineDueDataV1 = {
  deadline_id: UUID
  template_id: UUID | null
  type: string
  category?: string
  due_date: RFC3339
  frequency: string
  occurrence_at: RFC3339
}

type DeadlineGenerationFailedDataV1 = {
  deadline_id: UUID
  template_id: UUID | null
  category?: string
  occurrence_at: RFC3339
  retryable: boolean
  reason:
    | "business_refusal"
    | "budget_exceeded"
    | "sweep_cancelled"
    | "transient"
    | "unknown"
  error_summary: string
  failed_at: RFC3339
}

type RegulatoryDraftReadyDataV1 = {
  report_id: UUID
  document_id: string
  document_version: string
  template_id: string
  output_format: string
  draft_version: number
  required_gaps_count: number
  requested_by: string
  generated_at: RFC3339
}

type RegulatoryFilingApprovedDataV1 = {
  report_id: UUID
  document_id: string
  document_version: string
  template_id: string
  output_format: string
  artifact_object_key: string
  artifact_sha256: string
  artifact_size_bytes: number
  draft_version: number
  delivery_attempt: number
  parameters: Record<string, string>
  corrections_count: number
  corrected_by: string
  corrected_at: string
  approved_by: string
  approved_at: RFC3339
}

type RegulatoryVersionAdoptedDataV1 = {
  document_id: string
  previous_version: string
  adopted_version: string
  adopted_by: string
  adopted_at: RFC3339
  binding_gaps_count: number
  mapping_broken: boolean
}
```

`document_type` carrega a categoria do template. Ele contém uma string vazia na variante de falha do worker que não carrega `template_id`. Trate um valor vazio como ausência de categoria. `document_id` e `document_version` em `report.errored` nomeiam o documento regulatório quando uma inscrição gerou o relatório, e são strings vazias nos demais casos.

`artifact_object_key` em `report.finished`, `report.partial` e `regulatory.filing_approved` é a chave de armazenamento do arquivo exatamente como o Reporter a gravou, e nunca é vazia. Use-a como está. Não a reconstrua a partir de outros campos. Em `regulatory.filing_approved`, verifique o objeto armazenado contra `artifact_sha256` antes de enviá-lo. `parameters` carrega os parâmetros de geração sem os que começam com `system.`.

`binding_gaps_count` em `regulatory.version_adopted` conta os campos da versão adotada que o mapeamento existente deixa sem mapear. O campo `mapping_broken` é `true` quando o Reporter não conseguiu avaliar o mapeamento existente contra a versão adotada. Nesse caso, `binding_gaps_count` é 0.

## Canal de comando interno separado

O manager envia ao worker um comando JSON que não é CloudEvents pelo RabbitMQ. Ele usa `RABBITMQ_EXCHANGE`, `RABBITMQ_GENERATE_REPORT_KEY` e `RABBITMQ_GENERATE_REPORT_QUEUE`, com entrega persistente. Esse comando não faz parte do catálogo público de eventos, e o formato dele não é um contrato público.

## Status de eventos de entrada

O Reporter não consome nenhum evento de negócio público. O subscriber do Hub está indisponível: habilitá-lo é rejeitado na inicialização.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.