Eventos e Ciclo de Vida de Agendamentos (Appointments)
Pilar: 04 — Banco de Dados e Eventos / Eventos
Status: 🟢 Implementado
Última Revisão Técnica: 2026-08-03
Módulos Conectados:gatein-server(app/core/scheduler.py,app/api/web/appointments.py,app/api/public/appointments.py),gatein-app(src/screens/Home)
1. Visão Geral dos Eventos de Agendamento
O módulo de Appointments é a entidade operacional primária do ecossistema Gatein. Qualquer criação, alteração de janela temporal, cancelamento, notificação agendada ou auditoria de engajamento do motorista gera um evento registrado na tabela appointments_logs e dispara reações em tempo real ou agendadas.
sequenceDiagram
autonumber
actor ERP as Terminal / ERP (API Key / Web App)
participant S as Gatein Server (FastAPI)
participant SCHED as APScheduler Engine
participant DB as PostgreSQL
participant FCM as Firebase Messaging
actor M as Motorista (Mobile App)
ERP->>S: POST /web/appointments (Cria Agendamento com Ref + Janela + Driver TaxID)
S->>DB: Inserção do Appointment (Status: PLANNED ou ACTIVE)
S->>DB: Registra AppointmentLog (event: CREATED)
S->>FCM: notify_user_by_tax_id(type: APPOINTMENT_CREATED)
FCM-->>M: Notificação Push: "Novo Agendamento Criado!"
note over SCHED, DB: Jobs de Background Recorrentes
SCHED->>DB: Executa check_1day_reminders() (23h a 25h antes)
SCHED->>FCM: Push Batch (type: REMINDER_1DAY)
SCHED->>DB: Executa check_12h_reminders() (12h antes)
SCHED->>FCM: Push Batch (type: COUNTDOWN)
SCHED->>DB: Executa check_window_open() (Janela Aberta)
SCHED->>FCM: Push (type: WINDOW_OPEN)
M->>S: POST /mobile/activities/log-events (Visualizou / Clicou)
S->>DB: Registra AppointmentLog (event: VIEWED / CLICKED)
ERP->>S: POST /web/appointments/cancel (Cancela Agendamento)
S->>DB: Atualiza status -> CANCELLED
S->>DB: Registra AppointmentLog (event: DELETED / CHECKIN_CANCELLED)
S->>FCM: Push: "Agendamento Cancelado"
2. Dicionário de Eventos (AppointmentEvent)
Enum AppointmentEvent | Origem da Invocação | Descrição do Evento | Efeitos Colaterais / Notificações |
|---|---|---|---|
created | Web App / API Pública | Agendamento criado pelo Terminal/Transportador | Injeta log em appointments_logs e envia Push FCM APPOINTMENT_CREATED |
updated | Web App / API Pública | Alteração de janela, placa, carga ou layout_ref | Atualiza o banco, grava log em JSON e envia Push APPOINTMENT_UPDATED |
deleted | Web App / API Pública | Cancelamento ou soft-delete do agendamento | Transiciona status para CANCELLED/DELETED, cancela jobs e envia Push APPOINTMENT_CANCELLED |
notification_sent | APScheduler | Sucesso no envio de um lembrete em background | Grava em appointments_logs com json = {"push_type": "..."} para garantir idempotência |
checkin_cancelled | Endpoint /mobile/checkin/cancel | Reversão do check-in pelo motorista ou operador | Reverte status de CHECKED-IN para ACTIVE, registra justificativa e notifica motorista |
viewed | Mobile App (log-events) | Motorista expandiu o card do agendamento na tela | Registra telemetria do motorista (bateria, horário) sem enviar Push |
clicked | Mobile App (log-events) | Motorista clicou na ação principal do card | Registra telemetria de engajamento do motorista |
auto_deactivated | APScheduler (check_in_progress) | Agendamento mantido em IN_PROGRESS por > 24h | Marca status como COMPLETED/PAUSED por estouro de tempo limite |
3. Eventos Disparados por Background Jobs (APScheduler)
Os 4 jobs de background operam com verificação de idempotência baseada na tabela appointments_logs:
3.1 Evento REMINDER_1DAY
- Target SQL: Agendamentos com
status == 'ACTIVE'ewindow_startentrenow() + 23henow() + 25h. - Idempotência: Ignora agendamentos que já possuem um log em
appointments_logscomevent == 'notification_sent'ejson->>'push_type' == 'REMINDER_1DAY'.
3.2 Evento COUNTDOWN (12 Horas)
- Target SQL: Agendamentos com
status == 'ACTIVE'ewindow_startentrenow() + 11h52m30senow() + 12h07m30s. - Idempotência: Ignora agendamentos que já contêm log de
push_type == 'COUNTDOWN'. Envia payload comtarget_timestamppara a contagem regressiva local no app.
3.3 Evento WINDOW_OPEN
- Target SQL: Agendamentos ativos dentro da janela permitida (
(window_start - start_tolerance) <= now() <= (window_end + end_tolerance)). - Idempotência: Envia uma única notificação informando a abertura da janela e libera a ação de check-in remoto via GPS.
4. Regras de Negócio de Eventos de Agendamento (RN-EVT-APT-XXX)
RN-EVT-APT-001: Idempotência de Disparo em Lote
Antes de cada envio em massa de lembretes, o APScheduler consulta em lote os registros de appointments_logs. Agendamentos cujos lembretes já foram disparados anteriormente são filtrados antes da invocação da API do Firebase FCM, reduzindo o consumo de cota.
RN-EVT-APT-002: Gravação Auditável de Payload de Alteração
Sempre que o evento updated for disparado pela API, o campo json do log em appointments_logs gravará a diferença (diff) entre os atributos antigos e novos (ex: {"old_window_start": "...", "new_window_start": "..."}).
RN-EVT-APT-003: Cancelamento Cascata de Agendamentos e Check-ins
A ocorrência do evento deleted (cancelamento) em um agendamento forçará a invalidação imediata de qualquer solicitação de check-in pendente associada em checkins, enviando notificação Push com o motivo do cancelamento para o motorista.