feat(train-scheduling): implement day-level booking pool

- Added `unplaced` method in `BookingNotifierService` to log warnings for bookings that cannot be placed on any train.
- Introduced `getAvailableDays` method in `TrainSchedulingService` to retrieve distinct days with open departures for a given route.
- Created `AvailableDaysQueryDto` for querying available days based on origin and destination yards.
- Updated `TrainSchedulingController` to expose an endpoint for available days.
- Modified frontend components to support day-level booking, allowing customers to select only a day without pinning to a specific train.
- Removed references to train schedules in booking forms and review steps, emphasizing day selection.
- Added a database migration to create an index for efficient querying of bookings by route and day.
This commit is contained in:
Marshal
2026-06-18 14:12:46 +00:00
parent 578012dffd
commit 421e0266bc
22 changed files with 626 additions and 332 deletions

View File

@@ -55,6 +55,16 @@ function eatParts(date: Date): EatDateParts {
};
}
/**
* The EAT calendar day a timestamp falls on, as `yyyy-MM-dd`. This is the day
* key for day-level booking pools — it must match the day the portal calendar
* renders, so always derive day keys through this (never `toISOString().slice`).
*/
export function eatDay(date: Date): string {
const { year, month, day } = eatParts(date);
return `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
}
/** Build a UTC Date for a given EAT local wall-clock time on a calendar day. */
function eatToUtc(
year: number,