Pular para o conteúdo principal

Visão Geral do Sistema de Notificações

Pilar: 03 — Notificações
Status: 🟢 Implementado
Última Revisão Técnica: 2026-08-03
Módulos Conectados: gatein-server (app/core/scheduler.py, app/core/firebase.py), gatein-app (Notifee, @react-native-firebase/messaging)


1. Arquitetura Geral do Sistema de Notificações

O ecossistema Gatein conta com um motor de notificações assíncronas e em tempo real responsável por alertar motoristas no aplicativo mobile sobre agendamentos futuros, abertura de janelas de check-in, aprovações/rejeições de check-in em pátio, atualizações de viagens (trips), comunicados e eventos de segurança.

A arquitetura é dividida em duas vias principais:

  1. Envio Reativo (Event-Driven): Disparado no ato da execução de uma ação (ex: Terminal aprova check-in no Web App -> backend envia Push FCM imediatamente).
  2. Envio Agendado (Scheduled Jobs via APScheduler): Jobs em background rodando no servidor que monitoram o banco de dados PostgreSQL e enviam notificações agrupadas por usuário.

1.1 Diagrama de Arquitetura de Notificações

graph TD
subgraph Servidor (gatein-server)
APS[APScheduler Job Engine] -->|1h / 15m / 5m| DB[(PostgreSQL)]
API[FastAPI REST Handlers] -->|Eventos Imediatos| FCM_SDK[Firebase Admin SDK]
APS -->|Múltiplos Agendamentos| FCM_SDK
end

subgraph Firebase Cloud Messaging
FCM_SDK -->|Push SSL| FCM_CLOUD[Google FCM Cloud]
end

subgraph Dispositivo Mobile (gatein-app)
FCM_CLOUD -->|Background / Killed| RN_FB[@react-native-firebase/messaging]
FCM_CLOUD -->|Foreground| NOTIFEE[Notifee Library]
RN_FB -->|Deep Link| NAV[React Navigation]
NOTIFEE -->|System Tray Notification| NAV
end

2. Jobs Recorrentes do APScheduler (app/core/scheduler.py)

O servidor executa um BackgroundScheduler configurado no fuso horário America/Sao_Paulo com 5 jobs essenciais:

JobFrequênciaDescrição / Janela SelecionadaTipo de Push (data.type)
check_1day_remindersA cada 1 horaAgendamentos ativos com início entre +23h e +25hREMINDER_1DAY
check_12h_remindersA cada 15 minAgendamentos ativos com início entre +11h52m e +12h07mCOUNTDOWN
check_window_openA cada 5 minAgendamentos ativos no horário de janela aberta (window_open <= now <= window_close)WINDOW_OPEN
check_in_progressA cada 5 minAgendamentos em andamento há mais de 4h sem conclusãoIN_PROGRESS_CHECK
cleanup_dead_tokensDiário (03:00)Remove FCM Tokens inativos há mais de 90 dias do bancoN/A (Manutenção)

3. Canais do Notifee no App Mobile (Android & iOS)

Para garantir que o motorista perceba notificações críticas (como liberação de gate ou alertas de segurança) mesmo com o celular no bolso, o aplicativo mobile registra canais nativos via Notifee com prioridades distintas:

Canal NotifeeImportance (Android)Som / VibraçãoUso Operacional
checkinHIGH / HIGH_PRIORITYSom Customizado + Vibração PadrãoAprovação e Rejeição de Check-in em Pátio
appointmentDEFAULT / HIGHSom Padrão do SistemaLembretes de 1 dia, 12h e Janela Aberta
announcementLOW / MINSilencioso (Apenas Gaveta)Comunicados e Anúncios da Empresa
securityCRITICAL / MAXSom de Alarme ContinuoAlertas de Segurança e Desvio de Rota
tripHIGHSom Padrão do SistemaAtribuição de Nova Viagem de Frete

4. Ciclo de Vida do FCM Token

sequenceDiagram
autonumber
actor M as Motorista (Mobile)
participant APP as Gatein App (React Native)
participant FCM as Firebase Messaging
participant S as Gatein Server
participant DB as PostgreSQL

APP->>FCM: messaging().getToken()
FCM-->>APP: Retorna FCM Token Atual
APP->>S: POST /mobile/auth/register-fcm-token (fcm_token)
S->>DB: Salva drivers.fcm_token e drivers.token_updated_at
note over FCM, APP: Quando o Firebase renova o Token automaticamente
FCM->>APP: Evento onTokenRefresh(newToken)
APP->>S: POST /mobile/auth/register-fcm-token (newToken)
S->>DB: Atualiza token no banco
note over M, S: No Logout do Motorista
M->>APP: Clique em "Sair"
APP->>S: DELETE /mobile/auth/fcm-token
S->>DB: Define drivers.fcm_token = NULL

5. Regras de Negócio de Notificações (RN-NOTIF-XXX)

RN-NOTIF-001: Agrupamento de Notificações por Usuário (User Batching)

Nos jobs do APScheduler (check_1day_reminders e check_12h_reminders), caso um motorista possua múltiplos agendamentos dentro da mesma janela temporal, o servidor envia uma única notificação consolidada (ex: "Você possui 3 agendamentos amanhã"), prevenindo a fadiga de notificações.

RN-NOTIF-002: Idempotência de Envio por Agendamento

Para evitar duplicidade de disparos, o servidor verifica na tabela appointment_logs se já existe um evento NOTIFICATION_SENT gravado para o appointment_id especificando o mesmo push_type (REMINDER_1DAY, COUNTDOWN, WINDOW_OPEN). Se já tiver sido enviado, a notificação é ignorada.

RN-NOTIF-003: Purga Automática de Tokens Inválidos (Dead Tokens)

Se o serviço do FCM retornar os erros messaging/invalid-registration-token ou messaging/registration-token-not-registered, o servidor marca imediatamente o fcm_token do motorista como NULL na tabela drivers, evitando desperdício de requisições de rede.

RN-NOTIF-004: Persistência Obrigatória de Histórico no Banco

Toda notificação Push transacional disparada pelo servidor deve gravar obrigatoriamente uma linha na tabela notifications com os campos title, body, data (JSON) e is_read = False, alimentando a tela interna de histórico do aplicativo.