Uma TripSchedule é um template recorrente que materializa viagens (Trip) futuras vendáveis. Ela combina rota, veículo, motorista, frequência e paradas-template, e o sistema gera as ocorrências em um horizonte móvel de 90 dias.
Campos
| Campo | Tipo | Descrição |
|---|
tripScheduleId | UUID | Identificador único |
companyId | UUID | Empresa dona da programação (resolvida da rota) |
routeId | UUID | Rota das viagens geradas |
vehicleId | UUID | Veículo das viagens geradas |
driverId | UUID | Motorista das viagens geradas |
name | string | Nome da programação |
frequency | TripScheduleFrequency | DAILY, WEEKLY ou MONTHLY |
interval | integer | Intervalo entre ocorrências (padrão 1) |
status | TripScheduleStatus | ACTIVE, PAUSED ou ARCHIVED |
departureAt | datetime | Primeira partida programada |
endAt | datetime? | Fim opcional da recorrência |
createdBy | UUID? | Usuário que criou o registro, quando aplicável |
createdAt | datetime | Data de criação |
updatedBy | UUID? | Usuário que fez a última atualização, quando aplicável |
updatedAt | datetime | Data de última atualização |
deletedBy | UUID? | Usuário que removeu o registro, quando aplicável |
deletedAt | datetime? | Data de remoção |
Templates de parada e itinerário
As paradas-template vivem em TripScheduleStop, e os itinerários-template vivem em TripScheduleItinerary. Na materialização, esses templates produzem os TripStop e TripItinerary de cada viagem gerada.
| Entidade | Campos principais |
|---|
TripScheduleStop | pointId, stopOrder, arrivalOffsetMinutes, departureOffsetMinutes |
TripScheduleItinerary | fromStopOrder, toStopOrder, price |
Ciclo de vida
| Status | Descrição |
|---|
ACTIVE | Materializa viagens e participa da rotina diária de materialização. |
PAUSED | Fica fora da rotina diária de materialização. Pode voltar a ACTIVE. |
ARCHIVED | Arquivada. Não pode ser reativada. |
A atualização altera apenas o name. Pausar, retomar e arquivar são operações dedicadas.
Materialização
Horizonte e ocorrências
As ocorrências são calculadas a partir do momento atual até 90 dias à frente. Se endAt for anterior ao fim do horizonte, ele é o limite. Apenas ocorrências futuras dentro do limite entram. Há um teto de segurança de 10.000 iterações.
A partir de departureAt, cada ocorrência index avança por frequência:
| Frequência | Avanço |
|---|
DAILY | + index × interval dias |
WEEKLY | + index × interval × 7 dias |
MONTHLY | + index × interval meses |
Na frequência MONTHLY, quando o dia de origem não existe no mês de destino, a ocorrência é pulada. Ex.: uma programação que parte dia 31 não gera ocorrência em fevereiro.
Para cada ocorrência, estimatedArrivalAt = departureAt + max(route.estimatedDuration, maiorOffsetDeParada), e os horários das paradas são derivados dos offsets do template.
Preview e criação
- Preview calcula todo o horizonte de 90 dias e devolve, por ocorrência,
departureAt, estimatedArrivalAt, status e uma descrição.
- Criação materializa somente as
occurrences escolhidas pelo cliente e salva a programação. Candidatas conflitantes/duplicadas são ignoradas.
Avaliação das candidatas
Cada viagem candidata recebe um status antes de ser criada:
| Status | Quando |
|---|
MATERIALIZABLE | Sem duplicidade nem conflito — será criada. |
DUPLICATE | Já existe uma viagem com a mesma chave. |
CONFLICT | Sobreposição de horário com outra viagem que compartilha veículo ou motorista. |
A chave de agendamento é companyId | departureAt | routeId | vehicleId | driverId. Conflitos são detectados contra viagens SCHEDULED/IN_PROGRESS cujo intervalo [departureAt, estimatedArrivalAt) se sobrepõe.
Durante a materialização, candidatas DUPLICATE e CONFLICT são ignoradas. Somente as MATERIALIZABLE são criadas.
Idempotência
A idempotência é baseada na chave companyId | departureAt | routeId | vehicleId | driverId. Uma mesma viagem não é materializada duas vezes.
Criação das viagens
As viagens MATERIALIZABLE são criadas junto com suas paradas e itinerários.
Rotina diária de materialização
Uma rotina diária percorre as programações ACTIVE e rematerializa cada uma sobre o horizonte móvel de 90 dias, estendendo a cobertura conforme o tempo avança. Programações PAUSED/ARCHIVED são ignoradas. Falhas em uma programação não abortam as demais, e a idempotência impede a recriação de viagens já existentes.
Capacidades OPS
| Capacidade | Descrição |
|---|
| Listar programações | Lista programações recorrentes |
| Detalhar programação | Detalha uma programação |
| Preview | Calcula ocorrências do horizonte com status |
| Criar programação | Cria a programação e materializa as ocorrências escolhidas |
| Renomear programação | Atualiza o name |
| Pausar | Pausa a programação |
| Retomar | Retoma a programação |
| Arquivar | Arquiva a programação |