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:
- 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).
- 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:
| Job | Frequência | Descrição / Janela Selecionada | Tipo de Push (data.type) |
|---|---|---|---|
check_1day_reminders | A cada 1 hora | Agendamentos ativos com início entre +23h e +25h | REMINDER_1DAY |
check_12h_reminders | A cada 15 min | Agendamentos ativos com início entre +11h52m e +12h07m | COUNTDOWN |
check_window_open | A cada 5 min | Agendamentos ativos no horário de janela aberta (window_open <= now <= window_close) | WINDOW_OPEN |
check_in_progress | A cada 5 min | Agendamentos em andamento há mais de 4h sem conclusão | IN_PROGRESS_CHECK |
cleanup_dead_tokens | Diário (03:00) | Remove FCM Tokens inativos há mais de 90 dias do banco | N/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 Notifee | Importance (Android) | Som / Vibração | Uso Operacional |
|---|---|---|---|
checkin | HIGH / HIGH_PRIORITY | Som Customizado + Vibração Padrão | Aprovação e Rejeição de Check-in em Pátio |
appointment | DEFAULT / HIGH | Som Padrão do Sistema | Lembretes de 1 dia, 12h e Janela Aberta |
announcement | LOW / MIN | Silencioso (Apenas Gaveta) | Comunicados e Anúncios da Empresa |
security | CRITICAL / MAX | Som de Alarme Continuo | Alertas de Segurança e Desvio de Rota |
trip | HIGH | Som Padrão do Sistema | Atribuiçã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.