Skip to main content

Especificação do Sistema de Notificações Push (GateIn)

Este documento descreve detalhadamente todas as notificações push possíveis no ecossistema GateIn (para Agendamentos e Viagens), suas regras de disparo, motivos/objetivos de negócio, payloads de dados e a arquitetura de deduplicação para garantir que notificações agendadas sejam entregues uma única vez.


1. Visão Geral

As notificações no GateIn são processadas via Firebase Cloud Messaging (FCM) e enviadas aos dispositivos móveis dos motoristas com base no seu CPF (tax_id).

No backend (gatein-server), as notificações são disparadas em dois cenários principais:

  1. Eventos em Tempo Real (Event-Driven): Ações tomadas via API pública de integração (/api/v1/trips, /api/public/appointments), rotas do aplicativo ou handshakes Socket.IO com totens físicos de terminais.
  2. Jobs Automatizados (Cron / Scheduler): Tarefas executadas periodicamente pelo APScheduler para checar horários de agendamento/viagem, janelas de tolerância e inatividade.

2. Tabela Resumo de Notificações

note

Salvo indicação em contrário, todas as notificações são destinadas diretamente ao motorista responsável (user_tax_id / tax_id).

2.1. Notificações de Agendamentos (Terminais)

Código / typeTítulo ExibidoGatilho & OrigemObjetivo de Negócio
REMINDER_1DAYLembrete: amanhãJob Scheduler (24h antes)Alertar antecedência para planejamento de viagem.
COUNTDOWNEm breve!Job Scheduler (12h antes)Notificar 12h antes e fornecer contagem regressiva.
WINDOW_OPENJanela aberta!Job Scheduler (Início da janela)Avisar que o acesso ao pátio está liberado.
ON_GOINGEm andamentoJob Scheduler (Status ON_GOING)Orientar o motorista a seguir as instruções do terminal.
CANCELLEDAgendamento DesativadoJob / API (DELETE /appointments)Notificar cancelamento ou encerramento por inatividade.
SCHEDULED_CREATEDNovo agendamentoAPI pública (POST /appointments)Informar a criação de um novo agendamento.
SCHEDULED_UPDATEHorário alteradoAPI pública (PUT /appointments)Notificar remarcação de horários ou dados.
CHECKED-INCheck-in realizado!Handshake Socket (Totem)Confirmar recepção da senha/ticket no terminal.
CHECKIN_FAILEDFalha no check-inHandshake Socket (Timeout/Erro)Informar erro no totem para que o motorista retente.
CHECKIN_CANCELLEDCheck-in canceladoAPI (POST /checkin/cancel/{id})Confirmar reversão do status para Agendado.

2.2. Notificações de Viagens / Trips (Transportadoras)

Código / typeTítulo ExibidoGatilho & OrigemObjetivo de Negócio
TRIP_REMINDER_1DAYLembrete: Viagem amanhã!Job Scheduler (24h antes)Alertar o motorista sobre a viagem agendada para o dia seguinte.
TRIP_COUNTDOWNViagem em breve!Job Scheduler (12h antes)Notificar 12h antes com timestamp para contagem regressiva no app.
TRIP_WINDOW_OPENJanela da viagem aberta!Job Scheduler (Início da janela)Avisar que a janela de partida da viagem está liberada.
TRIP_IN_PROGRESSViagem em andamentoJob Scheduler / Status IN_PROGRESSOrientar o motorista sobre a rota em execução.
TRIP_CANCELLEDViagem CanceladaJob / API (DELETE /api/v1/trips)Notificar cancelamento manual ou desativação por tolerância.
TRIP_ASSIGNEDNova viagem atribuída!API pública (POST /api/v1/trips)Informar a criação e escalação do motorista para uma nova viagem.
TRIP_ROUTE_UPDATEDViagem AlteradaAPI pública (PUT /api/v1/trips)Notificar alteração em horários, rota (origem/destino) ou dados da viagem.
TRIP_COMPLETEDViagem Concluída!API pública (PUT /api/v1/trips)Confirmar a chegada ao destino e finalização da viagem.

2.3. Notificações Institucionais e Utilitárias

Código / typeTítulo ExibidoGatilho & OrigemObjetivo de Negócio
TESTNotificação de TesteAPI (POST /notifications/test)Validar recebimento de push e registro de tokens.
ANNOUNCEMENTTítulo do AnúncioPainel Web (POST /announcements)Comunicar avisos gerais e alertas do terminal/transportadora.

3. Detalhamento por Notificação

3.1. Notificações de Agendamentos (Scheduler)

1. Lembrete de 1 Dia (REMINDER_1DAY)

  • Regra: Filtra agendamentos ACTIVE cuja janela inicial (window_start) ocorrerá entre 23 e 25 horas no futuro.
  • Deduplicação: O job verifica na tabela appointments_logs se já existe registro com event = 'notification_sent' e push_type = 'REMINDER_1DAY'. Se existir, pula o envio.
  • Payload Data: {"type": "REMINDER_1DAY", "count": "1"}

2. Lembrete de 12 Horas (COUNTDOWN)

  • Regra: Filtra agendamentos ACTIVE que iniciarão em aproximadamente 12 horas (janela de ±7.5 minutos).
  • Deduplicação: Verifica se push_type = 'COUNTDOWN' já foi registrado para o agendamento em appointments_logs.
  • Payload Data: {"type": "COUNTDOWN", "appointment_id": "<id>", "target_timestamp": "<iso_date>", "count": "1"}
  • Comportamento no App: O aplicativo intercepta o tipo COUNTDOWN e pode exibir um timer/contagem regressiva local.

3. Janela Aberta (WINDOW_OPEN)

  • Regra: Filtra agendamentos ACTIVE em que o horário atual está dentro da janela de check-in (window_start - start_tolerance até window_end + end_tolerance).
  • Deduplicação: Disparado estritamente 1 única vez por agendamento. O scheduler consulta appointments_logs e, caso já tenha enviado a notificação de janela aberta para aquele agendamento, ignora nas execuções subsequentes de 5 em 5 minutos.
  • Payload Data: {"type": "WINDOW_OPEN", "appointment_id": "<id>", "window_close": "<iso_date>"}

4. Operação em Andamento (ON_GOING)

  • Regra: Filtra agendamentos que entraram no status ON_GOING.
  • Deduplicação: Disparado 1 única vez assim que a operação transiciona para em andamento.
  • Payload Data: {"type": "ON_GOING", "appointment_id": "<id>"}

5. Agendamento Desativado por Inatividade (CANCELLED / DEACTIVATED)

  • Regra: Disparado quando um agendamento é desativado automaticamente por ultrapassar a tolerância de 2 horas sem check-in ou sem ping do terminal.
  • Payload Data: {"type": "CANCELLED", "appointment_id": "<id>"}

3.2. Notificações de Integração de Agendamentos

6. Novo Agendamento Criado (SCHEDULED_CREATED)

  • Regra: Disparado via POST /api/public/appointments quando um novo agendamento é criado com o CPF do motorista.
  • Payload Data: {"type": "SCHEDULED_CREATED", "ref": "<ref_externa>"}

7. Alteração de Agendamento (SCHEDULED_UPDATE)

  • Regra: Disparado via PUT /api/public/appointments. Envia mensagem de horário alterado caso os campos de data/tolerância mudem, ou de dados atualizados para outros atributos.
  • Payload Data: {"type": "SCHEDULED_UPDATE", "ref": "<ref_externa>", "change": "time" | "display"}

8. Cancelamento de Agendamento (CANCELLED)

  • Regra: Disparado via DELETE /api/public/appointments quando a empresa cancela o agendamento.
  • Payload Data: {"type": "CANCELLED", "ref": "<ref_externa>"}

3.3. Notificações de Check-in e Hardware Terminal

9. Check-in Realizado (CHECKED-IN)

  • Regra: Disparado após confirmação do totem físico e geração dos tickets de acesso.
  • Payload Data: {"type": "CHECKED-IN"}

10. Falha no Check-in (CHECKIN_FAILED)

  • Regra: Disparado caso ocorra timeout (> 15s) ou falha no Socket de comunicação com o terminal físico.
  • Payload Data: {"type": "CHECKIN_FAILED"}

11. Check-in Cancelado (CHECKIN_CANCELLED)

  • Regra: Disparado quando o check-in é desfeito via POST /api/mobile/checkin/cancel/{appointment_id}.
  • Payload Data: {"type": "CHECKIN_CANCELLED", "appointment_id": "<id>", "reason": "<motivo>"}

3.4. Notificações Específicas e Personalizadas de Viagens (Trips)

12. Lembrete de Viagem de 1 Dia (TRIP_REMINDER_1DAY)

  • Regra: Filtra viagens ativas (PLANNED/ACTIVE) cujo window_start ocorrerá entre 23 e 25 horas no futuro.
  • Deduplicação: O job verifica na tabela trips_logs se já existe log com event = 'notification_sent' e json.push_type = 'TRIP_REMINDER_1DAY'.
  • Payload Data: {"type": "TRIP_REMINDER_1DAY", "trip_id": "<id>", "ref": "<ref>"}

13. Contagem Regressiva da Viagem (TRIP_COUNTDOWN)

  • Regra: Filtra viagens ativas em que o window_start ocorrerá em aproximadamente 12 horas (janela de ±7.5 minutos).
  • Deduplicação: Consulta em trips_logs por push_type = 'TRIP_COUNTDOWN'.
  • Payload Data: {"type": "TRIP_COUNTDOWN", "trip_id": "<id>", "ref": "<ref>", "target_timestamp": "<iso_date>"}

14. Janela de Viagem Aberta (TRIP_WINDOW_OPEN)

  • Regra: Filtra viagens ativas em que a hora atual está dentro do intervalo [window_start - start_tolerance, window_end + end_tolerance].
  • Deduplicação: Disparado 1 única vez por viagem. Registrado em trips_logs com push_type = 'TRIP_WINDOW_OPEN'.
  • Payload Data: {"type": "TRIP_WINDOW_OPEN", "trip_id": "<id>", "ref": "<ref>", "window_close": "<iso_date>"}

15. Viagem em Andamento (TRIP_IN_PROGRESS)

  • Regra: Filtra viagens com status IN_PROGRESS.
  • Deduplicação: Disparado 1 única vez assim que a viagem entra em andamento. Registrado em trips_logs com push_type = 'TRIP_IN_PROGRESS'.
  • Payload Data: {"type": "TRIP_IN_PROGRESS", "trip_id": "<id>", "ref": "<ref>"}

16. Viagem Atribuída (TRIP_ASSIGNED)

  • Regra: Disparado em tempo real via POST /api/v1/trips quando uma nova viagem é criada e atribuída a um motorista.
  • Payload Data: {"type": "TRIP_ASSIGNED", "trip_id": "<id>", "ref": "<ref>"}

17. Alteração de Rota/Horário da Viagem (TRIP_ROUTE_UPDATED)

  • Regra: Disparado em tempo real via PUT /api/v1/trips quando dados da viagem, locais de origem/destino ou janela de horário são alterados pela transportadora.
  • Payload Data: {"type": "TRIP_ROUTE_UPDATED", "trip_id": "<id>", "ref": "<ref>"}

18. Viagem Concluída (TRIP_COMPLETED)

  • Regra: Disparado em tempo real via PUT /api/v1/trips quando o status da viagem é atualizado para COMPLETED.
  • Payload Data: {"type": "TRIP_COMPLETED", "trip_id": "<id>", "ref": "<ref>"}

19. Viagem Cancelada ou Desativada (TRIP_CANCELLED)

  • Regra: Disparado via DELETE /api/v1/trips quando a transportadora cancela a viagem ou via job do scheduler quando a janela encerra há mais de 2 horas sem conclusão.
  • Payload Data: {"type": "TRIP_CANCELLED", "trip_id": "<id>", "ref": "<ref>"}

3.5. Notificações Utilitárias e Institucionais

20. Notificação de Teste (TEST)

  • Regra: Disparado manualmente via POST /api/mobile/notifications/test.
  • Payload Data: {"type": "TEST"}

21. Anúncios da Empresa / Terminal (ANNOUNCEMENT)

  • Regra: Disparado na publicação de novos anúncios para motoristas associados ao terminal/transportadora.
  • Payload Data: {"type": "ANNOUNCEMENT", "announcement_id": "<id>"}

4. Regra de Deduplicação e Envio Único

Para sanar a ocorrência de notificações repetidas durante as janelas operacionais (onde os jobs do scheduler rodam periodicamente a cada 5 ou 15 minutos), o sistema utiliza o mecanismo de Deduplicação por Log:

sequenceDiagram
participant S as Scheduler (APScheduler)
participant DB as PostgreSQL DB
participant L as Logs (Appointments / Trips Logs)
participant FCM as Firebase FCM / Mobile

S->>DB: Query agendamentos/viagens ativos na janela
DB-->>S: Retorna lista de registros
S->>L: Consulta logs de notificações já enviadas (event='notification_sent')
L-->>S: Retorna IDs com push_type correspondente (ex: 'TRIP_WINDOW_OPEN')
loop Para cada registro
alt ID já presente nos logs enviados
S->>S: Ignora envio (já notificado)
else ID novo
S->>FCM: Dispara push notification para o CPF do motorista
S->>L: Grava log com event='notification_sent' e json.push_type
end
end

Tanto os agendamentos (appointments_logs) quanto as viagens (trips_logs) armazenam a chave push_type no campo json do log do evento notification_sent. Antes de disparar qualquer notificação push automatizada, o sistema realiza essa verificação e previne qualquer reenvio indesejado.