Skip to main content
Toda mutação de domínio publica um evento. É isso que impede que os módulos que os consomem se acoplem uns aos outros diretamente — e é daqui que os webhooks de saída tiram os fatos que entregam.

O contrato do outbox

Um evento é escrito na mesma transação das linhas que ele descreve. Essa única regra compra a garantia que importa: um evento nunca descreve uma escrita que sofreu rollback, e uma escrita que comitou nunca deixa de produzir seu evento. Publicar depois do commit tornaria os dois possíveis, e os dois são o tipo de bug que aparece como “o contador está errado às vezes”. Depois do commit, a API cutuca a fila para drenar o outbox. A cutucada é best-effort: ela compra latência. Uma varredura periódica é o que de fato garante a drenagem, mesmo quando toda cutucada se perde.

O que é publicado hoje

Todo evento carrega a organização a que pertence; os do plano de clientes carregam também o ambiente. Os seis eventos de cobrança são o que o gateway diz, espelhado — nunca o que alguém pediu a ele. Mudar de plano pela API é um pedido que o gateway aceita, e qual é o plano depois disso chega com a resposta dele: os eventos acima são publicados quando a cópia local de fato se move, seja porque um webhook chegou, seja porque uma releitura noturna encontrou uma mensagem que nunca chegou. Então dá para construir em cima deles, e eles não são um log de chamadas de API.

contact.identified dispara uma vez

Só na transição de verdade. Um segundo magic link é um login, não uma segunda identificação — o SQL que marca o contato como identificado informa se mudou alguma coisa, e o evento só é publicado quando mudou.

Payloads carregam ids

Ids, não valores. Consumidores releem a linha, o que mantém endereços de e-mail e nomes fora de toda fila, log e buffer de retry por onde o envelope passa. Também significa que um consumidor atrasado lê o estado atual em vez de uma cópia velha.

Entrega é ao menos uma vez, e fora de ordem

Duas propriedades que valem no barramento e valem igual no seu endpoint: a mesma entrega pode chegar duas vezes, e a ordem de chegada não é a ordem dos fatos. Cada envelope carrega uma sequência global atribuída no commit — é ela que ordena, não o relógio da chegada.

Webhooks de saída

Eles são mais um consumidor dos eventos acima, em vez de um segundo caminho de publicação costurado por todo handler — que é justamente o motivo de o barramento vir primeiro, e por que nada da lista mudou de formato quando eles chegaram. O contrato de entrega viaja junto: id para deduplicar, sequence para ordenar. Veja webhooks de saída. Um fato é publicado aqui e deliberadamente nunca entregue para fora, webhook.endpoint_disabled: ele seria endereçado ao endpoint que acabou de parar de responder.