Support schedule trip variants

This commit is contained in:
2026-05-22 02:07:05 +03:00
parent 4a607d448b
commit edf3c1052b
7 changed files with 922 additions and 196 deletions

View File

@@ -160,9 +160,10 @@
### Schedule
- Таблица: `schedules`
- Поля: `id`, `route_id`, `day_type`, `departure_times`, `valid_from`, `valid_until`, `created_at`, `updated_at`
- Поля: `id`, `route_id`, `day_type`, `departure_times`, `trips`, `valid_from`, `valid_until`, `created_at`, `updated_at`
- Enum `day_type`: `weekday`, `saturday`, `sunday`, `holiday`
- `departure_times` хранится как массив `TIME[]`
- `trips` хранит расширенное описание каждого рейса: `departureTime`, `startStopId`, `endStopId`, `viaStopIds`, `daysOfWeek`, `exceptDaysOfWeek`, `note`. Это покрывает рейсы “с/до остановки”, “через остановку”, “по пятницам” и “кроме пятницы”.
### Holiday
@@ -242,8 +243,9 @@
### Schedule DTO
- `CreateScheduleRequest`: `{ routeId: number, dayType: ScheduleDayType, departureTimes: string[], validFrom?: string|null, validUntil?: string|null }`
- `UpdateScheduleRequest`: `{ departureTimes?: string[], validFrom?: string|null, validUntil?: string|null }`
- `ScheduleTrip`: `{ departureTime: string, startStopId?: number|null, endStopId?: number|null, viaStopIds?: number[], daysOfWeek?: number[], exceptDaysOfWeek?: number[], note?: string }`, где дни недели — ISO `1..7`, `1 = Monday`, `7 = Sunday`
- `CreateScheduleRequest`: `{ routeId: number, dayType: ScheduleDayType, departureTimes?: string[], trips?: ScheduleTrip[], validFrom?: string|null, validUntil?: string|null }`
- `UpdateScheduleRequest`: `{ departureTimes?: string[], trips?: ScheduleTrip[], validFrom?: string|null, validUntil?: string|null }`
- `CopyScheduleRequest`: `{ fromDayType: ScheduleDayType, toDayType: ScheduleDayType }`
### Holiday DTO
@@ -715,7 +717,7 @@
### [POST] /api/v1/routes/:routeId/schedules/copy
- Описание: копирует departure times из одного day type в другой
- Описание: копирует `departure_times` и расширенные `trips` из одного day type в другой
- Авторизация: Bearer JWT или `X-API-Key`
- Параметры path: `routeId`
- Query-параметры: нет
@@ -756,9 +758,9 @@
- Request Body: `CreateScheduleRequest`
- Response 200/201: созданный `Schedule`
- Ошибки:
- `400` — нет `routeId`, `dayType` или `departureTimes`
- `400` — нет `routeId`, `dayType` или одного из полей `departureTimes`/`trips`
- `400` — invalid `dayType`
- `400` — invalid departure time format, ожидается `HH:MM` или `HH:MM:SS`
- `400` — invalid departure time/trip format, ожидается `HH:MM` или `HH:MM:SS`, для `trips` также валидируются ISO weekdays `1..7`
- `409` — уже есть активное расписание на этот `routeId + dayType`
- `401`/`403`/`429`
- `500` — `Failed to create schedule`
@@ -767,7 +769,7 @@
### [PUT] /api/v1/schedules/:id
- Описание: обновляет departure times и/или validity window
- Описание: обновляет departure times, trips и/или validity window
- Авторизация: Bearer JWT или `X-API-Key`
- Параметры path: `id`
- Query-параметры: нет
@@ -776,7 +778,7 @@
- Response 200/201: обновленный `Schedule`
- Ошибки:
- `404` — расписание не найдено
- `400` — invalid departure time format
- `400` — invalid departure time/trip format
- `401`/`403`/`429`
- `500` — `Failed to update schedule`
- Связанные сущности: `Schedule`

View File

@@ -1960,6 +1960,43 @@ components:
ScheduleDayType:
type: string
enum: [weekday, saturday, sunday, holiday]
ScheduleTrip:
type: object
required: [departureTime]
properties:
departureTime:
type: string
description: Departure time in HH:MM or HH:MM:SS format.
startStopId:
type: integer
nullable: true
description: Optional stop id where a partial trip starts.
endStopId:
type: integer
nullable: true
description: Optional stop id where a partial trip ends.
viaStopIds:
type: array
items:
type: integer
description: Optional via-stop markers for display and route variants.
daysOfWeek:
type: array
items:
type: integer
minimum: 1
maximum: 7
description: ISO weekdays when this trip runs, 1=Monday, 7=Sunday.
exceptDaysOfWeek:
type: array
items:
type: integer
minimum: 1
maximum: 7
description: ISO weekdays when this trip does not run.
note:
type: string
description: Human-readable note such as "по пятницам" or "через Мариненко".
AlertType:
type: string
enum: [delay, cancellation, detour, info]
@@ -2132,6 +2169,10 @@ components:
type: array
items:
type: string
trips:
type: array
items:
$ref: '#/components/schemas/ScheduleTrip'
valid_from:
type: string
format: date
@@ -2720,7 +2761,7 @@ components:
type: integer
CreateScheduleRequest:
type: object
required: [routeId, dayType, departureTimes]
required: [routeId, dayType]
properties:
routeId:
type: integer
@@ -2730,6 +2771,11 @@ components:
type: array
items:
type: string
description: Legacy flat departure list. If trips is supplied, departureTimes is derived from trips.
trips:
type: array
items:
$ref: '#/components/schemas/ScheduleTrip'
validFrom:
type: string
format: date
@@ -2745,6 +2791,11 @@ components:
type: array
items:
type: string
description: Legacy flat departure list. If trips is supplied, departureTimes is derived from trips.
trips:
type: array
items:
$ref: '#/components/schemas/ScheduleTrip'
validFrom:
type: string
format: date