Eventos
Versão: 1.0
Owner: Engenharia SOFIA
Última revisão: 2026
Aplicável a: Dev Integradores, Backend, Infra e Auditoria Técnica
Esta página define o contrato oficial de eventos da SOFIA. Eventos podem ser entregues via:
- Webhook
- WebSocket
- postMessage (iframe)
Independentemente do canal, o envelope lógico do evento deve ser tratado como único e idempotente.
1. Envelope Padrão (Obrigatório)
Todos os eventos entregues por webhook ou stream seguem o padrão:
{
"event_name": "balance_update",
"event_id": "evt_01HRN7JQ3F7Z7C8D7J0R8V9J0Y",
"version": "2026-02-01",
"timestamp": "2026-02-21T13:45:12.123Z",
"environment": "production",
"data": {},
"meta": {}
}Campos obrigatórios
event_name— nome oficial (snake_case)event_id— identificador global imutávelversion— versão do contrato do eventotimestamp— ISO-8601 UTCenvironment—sandbox|productiondata— payload específicometa— metadados opcionais
2. Regras Gerais
- Eventos podem ser reenviados.
- Eventos podem chegar fora de ordem.
- Eventos podem ser entregues mais de uma vez.
- Idempotência é obrigatória para webhooks.
Nunca confie em ordenação implícita de rede.
3. Catálogo Oficial
3.1 balance_update
Quando ocorre
- Alteração de saldo
- Leitura de saldo no contexto do iframe
- Atualização em stream ativo
Canais
- postMessage
- WebSocket (quando habilitado)
- opcionalmente webhook
Campos mínimos
{
"balance": 123.45,
"currency": "BRL"
}3.2 bet_open
Quando ocorre
- Janela de aposta aberta
- Sinal ativo dentro do período válido
Canais
- Webhook (produção recomendado)
- WebSocket
Campos mínimos
{
"bet_id": "bet_123",
"table_id": "tbl_megaroulette",
"selection": {},
"valid_until": "2026-02-21T14:00:00Z"
}Opcional:
stakestrategy_id
3.3 bet_close
Quando ocorre
- Janela expirada
- Aposta concluída
- Cancelamento manual ou automático
Campos mínimos
{
"bet_id": "bet_123",
"reason": "expired",
"result": {}
}Valores possíveis de reason:
expiredcompletedcanceled
3.4 account_linked
Quando ocorre
- Conta autorizada com sucesso
{
"account_id": "acc_456",
"provider": "provider_name",
"status": "linked"
}3.5 account_unlinked
Quando ocorre
- Revogação
- Expiração
- Logout
- Falha de autorização
{
"account_id": "acc_456",
"provider": "provider_name",
"status": "unlinked",
"reason": "revoked"
}Valores possíveis de reason:
revokedexpireduser_actionsystem_action
4. Eventos via postMessage (Iframe)
Formato típico:
interface IframeMessage {
type: string;
data: unknown;
timestamp: string;
source: 'betting-iframe';
}Eventos comuns:
connection_statusbalance_updatebet_placedbet_resultautomation_statuserror
Regras obrigatórias
- Validar
event.origin - Definir
targetOrigin - Nunca usar
'*'em produção - Tratar
errorcomo estado degradado
5. WebSocket (Formato Observado)
{
"channel": "betting",
"type": "betting_update",
"update": {},
"timestamp": "2026-02-21T13:45:12.123Z"
}Integradores devem:
- Reconectar automaticamente
- Implementar backoff exponencial
- Tratar desconexão como estado temporário
6. Versionamento
Mudanças não-breaking
- Adição de campos opcionais
Mudanças breaking
- Alteração de tipo
- Remoção de campo
- Renomeação
Breaking change exige nova version.
Integrações devem ser tolerantes a campos adicionais.
7. Idempotência (Obrigatório)
event_id é chave única.
O integrador deve:
- Persistir
event_id - Ignorar duplicados
- Definir janela mínima de retenção (recomendado: 24h+)
Exemplo simplificado:
function shouldProcess(eventId: string): boolean {
// Persistir em banco/redis em produção
return true;
}Implementação em memória não é suficiente para produção.
8. Ordenação e Consistência
Não assumir ordem de chegada.
Se seu sistema depende de sequência (bet_open → bet_close):
- Use
bet_id - Mantenha máquina de estados
- Valide transições permitidas
9. Segurança
- Nunca logar payloads completos contendo dados sensíveis
- Validar assinatura HMAC em webhooks
- Rejeitar eventos fora da janela aceitável de timestamp
- Monitorar taxa de falhas