Uma Trip representa uma viagem agendada — a combinação de uma rota, um veículo e um motorista em uma data/hora específica. É a entidade central do domínio de Operations.
Máquina de Estados
TripStatus
| Status | Descrição |
|---|
SCHEDULED | Viagem agendada. Disponível para venda enquanto departureAt for futuro. |
IN_PROGRESS | Viagem em andamento. |
COMPLETED | Viagem concluída. |
CANCELLED | Viagem cancelada. |
Transições
| De | Para | Regra |
|---|
SCHEDULED | IN_PROGRESS | Só viagens agendadas podem iniciar |
IN_PROGRESS | COMPLETED | Só viagens em andamento podem concluir |
SCHEDULED / IN_PROGRESS | CANCELLED | Viagens concluídas ou já canceladas não podem ser canceladas |
Cada transição atualiza o status da viagem.
As transições são explícitas. Horário de partida e registro de embarque não alteram o status por conta própria. Registrar BOARDING_COMPLETED mantém a viagem no status atual.
Disponibilidade
Uma viagem é considerada disponível para venda quando está SCHEDULED e departureAt ainda é futuro. A busca de ofertas só retorna viagens nessa condição.
Rastreamento GPS
Trip não guarda campos de tracking diretamente. O último ping GPS aceito fica na tabela auxiliar 1:1 TripTracking.
| Regra | Descrição |
|---|
| Status permitido | GPS só é aceito quando a Trip está IN_PROGRESS. |
| Tabela auxiliar | Cada Trip pode ter no máximo um TripTracking. |
| Último ponto | latitude, longitude, accuracyMeters, speedKmh, headingDegrees e acceptedAt em TripTracking representam o último ping aceito. |
| Atualização | Cada novo ping aceito atualiza o mesmo TripTracking da viagem. |
| Sem histórico | TripTracking não guarda pings antigos. |
- Fleet: a Trip referencia um Vehicle e um Driver da empresa.
- Operations: a Trip contém TripStops (paradas) e TripItineraries (trechos compráveis); a venda de tickets gera TripSeatSegments.
- Sales: Orders e Tickets são vendidos referenciando os TripItineraries da viagem.
Criação avulsa de viagem
Criação avulsa registra uma única viagem.
Dados esperados
| Campo | Descrição |
|---|
routeId | Rota da viagem |
vehicleId | Veículo escalado |
driverId | Motorista escalado |
departureAt | Data/hora de partida |
estimatedArrivalAt | Data/hora estimada de chegada |
stops | Paradas físicas da viagem |
itineraries | Trechos vendáveis entre paradas |
A empresa (companyId) vem do escopo da organização autenticada. Os itinerários referenciam paradas por stopOrder.
Fluxo passo-a-passo
Validações na criação
| Validação | Comportamento |
|---|
| Rota pertence à organização | Rota de outra organização retorna 404 |
| Conflito de horário do veículo | Sobreposição de janela [departureAt, estimatedArrivalAt) com viagens SCHEDULED/IN_PROGRESS do mesmo veículo → vehicle_conflict |
| Conflito de horário do motorista | Mesma checagem para o motorista → driver_conflict |
A criação avulsa valida escopo da rota e conflitos de horário de veículo e motorista.
Geração de TripStops e TripItineraries
Os TripStops representam as paradas físicas da viagem; os TripItineraries referenciam pares de paradas como trechos compráveis.
Exemplo: viagem São Paulo → Campinas → Ribeirão Preto
TripStops (nome resolvido via pointId no catálogo global):
| stopOrder | Point | departureAt | arrivalAt |
|---|
| 0 | São Paulo | 08:00 | null |
| 1 | Campinas | 09:45 | 09:30 |
| 2 | Ribeirão Preto | null | 12:00 |
TripItineraries:
| TripItinerary | fromStopOrder | toStopOrder | Preço |
|---|
| SP → Campinas | 0 | 1 | R$ 50,00 |
| Campinas → Ribeirão | 1 | 2 | R$ 40,00 |
| SP → Ribeirão (direto) | 0 | 2 | R$ 80,00 |
É possível criar itinerários para trechos intermediários e para o trajeto completo, cada um com preço independente. Isso permite precificação flexível — o trecho completo pode custar menos que a soma dos parciais.
Materialização a partir de programações
Além da criação avulsa, viagens são geradas em lote a partir de uma programação recorrente (TripSchedule). A programação define rota, veículo, motorista, frequência e paradas-template, e o DEVMOB materializa as ocorrências em um horizonte móvel de 90 dias.
Cada viagem candidata é avaliada antes da criação: candidatas duplicadas ou em conflito são ignoradas, e somente as MATERIALIZABLE são criadas. Detalhes de frequência, idempotência e detecção de conflitos estão na página de Trip Schedules.
Cancelamento
O cancelamento marca a viagem como CANCELLED. Tickets, orders, payments e receivables permanecem fora do escopo dessa operação.