automate the schedule

This commit is contained in:
Marshal
2026-06-11 19:42:23 +00:00
parent f85c13ce8c
commit cde3e462ba
28 changed files with 1197 additions and 12 deletions

View File

@@ -22,14 +22,19 @@ import { PreviewBulkTrainScheduleDto } from './dto/preview-bulk-train-schedule.d
import { PreviewContainerTrainScheduleDto } from './dto/preview-container-train-schedule.dto';
import { PreviewTrainScheduleDto } from './dto/preview-train-schedule.dto';
import { RecordCheckpointDto } from './dto/record-checkpoint.dto';
import { BookableSchedulesQueryDto } from './dto/bookable-schedules-query.dto';
import { UpdateTrainSchedulingGlobalRulesDto } from './dto/update-train-scheduling-global-rules.dto';
import { TrainSchedulingService } from './train-scheduling.service';
import { BookingBatchService } from './booking-batch.service';
@ApiTags('train-scheduling')
@ApiBearerAuth()
@Controller('train-scheduling')
export class TrainSchedulingController {
constructor(private readonly trainSchedulingService: TrainSchedulingService) {}
constructor(
private readonly trainSchedulingService: TrainSchedulingService,
private readonly bookingBatchService: BookingBatchService,
) {}
@Get('global-rules')
@TrainSchedulingView()
@@ -52,6 +57,16 @@ export class TrainSchedulingController {
return this.trainSchedulingService.getEligibleBookings(query);
}
@Get('bookable-schedules')
@TrainSchedulingView()
@ApiOperation({ summary: 'OPEN same-route schedules a new booking can target' })
getBookableSchedules(@Query() query: BookableSchedulesQueryDto) {
return this.trainSchedulingService.getBookableSchedules(
query.originYardId,
query.destinationYardId,
);
}
@Get('container/eligible-bookings')
@TrainSchedulingView()
@ApiOperation({ summary: 'List eligible container bookings' })
@@ -162,6 +177,54 @@ export class TrainSchedulingController {
return this.trainSchedulingService.dispatchSchedule(id);
}
// ---- batch / booking-window staff actions ----
@Post('schedules/:id/run-batch')
@TrainSchedulingManage()
@ApiOperation({ summary: 'Manually run the batch fill for a schedule' })
async runBatch(@Param('id', ParseUUIDPipe) id: string) {
await this.bookingBatchService.fillSchedule(id);
return this.trainSchedulingService.getContainerTrainScheduleById(id);
}
@Patch('schedules/:id/booking-window')
@TrainSchedulingManage()
@ApiOperation({ summary: 'Open or close a schedule booking window' })
async setBookingWindow(
@Param('id', ParseUUIDPipe) id: string,
@Body('status') status: 'OPEN' | 'CLOSED',
) {
await this.trainSchedulingService.setBookingWindow(id, status === 'CLOSED' ? 'CLOSED' : 'OPEN');
return this.trainSchedulingService.getContainerTrainScheduleById(id);
}
@Post('bookings/:bookingId/mark-paid')
@TrainSchedulingManage()
@ApiOperation({ summary: 'Staff: mark a reserved booking paid and allocate it now' })
async markBookingPaid(@Param('bookingId', ParseUUIDPipe) bookingId: string) {
await this.bookingBatchService.markPaid(bookingId);
return { ok: true };
}
@Post('bookings/:bookingId/expire')
@TrainSchedulingManage()
@ApiOperation({ summary: 'Staff: expire a reservation and free its capacity' })
async expireBooking(@Param('bookingId', ParseUUIDPipe) bookingId: string) {
await this.bookingBatchService.expireReservation(bookingId);
return { ok: true };
}
@Post('bookings/:bookingId/move-schedule')
@TrainSchedulingManage()
@ApiOperation({ summary: 'Re-point a booking to another OPEN same-route schedule' })
async moveBookingSchedule(
@Param('bookingId', ParseUUIDPipe) bookingId: string,
@Body('trainScheduleId', ParseUUIDPipe) trainScheduleId: string,
) {
await this.bookingBatchService.moveToSchedule(bookingId, trainScheduleId);
return { ok: true };
}
@Get('schedules/:id/checkpoints')
@TrainSchedulingView()
@ApiOperation({ summary: 'Get the tracking corridor + logged checkpoints for a train' })