Política de Retry e Tolerância a Falhas de Notificação
Pilar: 03 — Notificações
Status: 🟡 Parcial
Última Revisão Técnica: 2026-08-03
Módulos Conectados:gatein-server(app/core/firebase.py,app/models.py)
1. Visão Geral da Resiliência do Envio Push
O serviço de notificações Push depende de infraestruturas terceiras (Google Firebase Cloud Messaging e Apple Push Notification Service - APNs). Por se tratar de redes sem fio com conexões oscilantes em estradas e pátios, o servidor implementa uma política de retry inteligente para garantir a entrega sem causar duplicação de mensagens.
2. Categorização de Erros e Ações Recomendadas
Ao tentar despachar uma notificação via firebase_admin.messaging.send(), o servidor trata as exceções conforme a classificação abaixo:
graph TD
TRY[Envio FCM Push] --> RES{Resultado}
RES -->|Sucesso| LOG_OK[Grava notifications.is_sent = True]
RES -->|Erro Temporário: 503 / Timeout / Unavailable| RETRY[Reenfileira com Backoff Exponencial]
RES -->|Erro Permanente: Token Inválido / Not Registered| INVALID[Define drivers.fcm_token = NULL]
RES -->|Erro de Autenticação / Service Account| ALERT[Alerta de Infraestrutura no Log]
2.1 Tabela de Classificação de Erros FCM
| Exceção FCM / Error Code | Tipo de Falha | Ação do Servidor | Número Máximo de Retentativas |
|---|---|---|---|
messaging/unreachable / unavailable | Temporária (Rede/Servidor FCM) | Retry com Backoff Exponencial | 3 tentativas |
messaging/quota-exceeded | Temporária (Rate Limit) | Retry estendido | 5 tentativas |
messaging/registration-token-not-registered | Permanente (App desinstalado / Token expirado) | Invalida Token no Banco (fcm_token = NULL) | 0 (Sem retry) |
messaging/invalid-argument | Permanente (Payload malformado) | Log de Erro de Código | 0 (Sem retry) |
messaging/authentication-error | Crítica de Infraestrutura | Notifica equipe de engenharia | 0 (Sem retry) |
3. Algoritmo de Backoff Exponencial
Para retentativas em falhas temporárias de rede, o servidor aplica o algoritmo de backoff exponencial com variação aleatória (jitter) para prevenir picos de requisição simultâneos:
Delay(n) = min(MaxDelay, BaseDelay * 2^n + rand(0, 1000ms))
- Tentativa 1 (Imediata): 0s.
- Tentativa 2: 5 segundos + Jitter.
- Tentativa 3: 30 segundos + Jitter.
- Tentativa 4 (Final): 5 minutos.
Se todas as 3 retentativas falharem, o envio é marcado como falhado na tabela notifications com o campo fcm_error preenchido.
4. Tabela de Auditoria de Falhas (notification_failures)
Para notificações operacionais de alta prioridade (como SECURITY_ALERT e CHECKIN_APPROVED), o servidor grava as falhas permanentes na tabela notification_failures:
| Coluna | Tipo SQL | Descrição |
|---|---|---|
id | UUID | ID do registro de falha |
driver_id | UUID | ID do motorista afetado |
push_type | VARCHAR(64) | Tipo da notificação (ex: CHECKIN_APPROVED) |
payload | JSONB | Payload bruto que falhou no envio |
error_code | VARCHAR(128) | Código exato da exceção retornada pelo FCM |
retry_count | INTEGER | Número total de tentativas realizadas |
failed_at | TIMESTAMPTZ | Timestamp da falha definitiva |
5. Regras de Negócio (RN-RETRY-XXX)
RN-RETRY-001: Anulação de Retry em Caso de Invalidação Explicita
Se um agendamento for cancelado enquanto o job de retry de notificação estiver em andamento, a próxima tentativa de envio verificará o status atual no PostgreSQL e abortará o disparo.
RN-RETRY-002: Notificação Não-Bloqueante para APIs REST
O envio de notificações push síncronas durante chamadas de API (como aprovação de check-in no Web App) nunca pode travar ou reverter a transação de banco de dados em caso de falha de rede com o FCM. A alteração de estado no banco é persistida primeiro; a falha do FCM é capturada e tratada em segundo plano.