mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 15:30:56 +00:00
102 lines
5.3 KiB
TypeScript
102 lines
5.3 KiB
TypeScript
import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common';
|
||
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiBody, ApiResponse } from '@nestjs/swagger';
|
||
import { FleetService } from './fleet.service';
|
||
import { CreateTrainDto, CreateCoachDto, UpdateCoachDto, AssignCoachDto, CreateSeatBatchDto, ListCoachesDto } from './fleet.dto';
|
||
import { JwtGuard } from '../../common/jwt.guard';
|
||
|
||
@ApiTags('Fleet')
|
||
@Controller('fleet')
|
||
@UseGuards(JwtGuard)
|
||
@ApiBearerAuth('JWT-auth')
|
||
export class FleetController {
|
||
constructor(private service: FleetService) {}
|
||
|
||
@Get('trains')
|
||
@ApiOperation({ summary: 'List all trains with their recent schedules' })
|
||
@ApiResponse({ status: 200, description: 'Array of trains each with up to 5 most recent schedules' })
|
||
getTrains() { return this.service.getTrains(); }
|
||
|
||
@Post('trains')
|
||
@ApiOperation({ summary: 'Create a train service' })
|
||
@ApiBody({ type: CreateTrainDto })
|
||
@ApiResponse({ status: 201, description: 'Train created' })
|
||
createTrain(@Body() dto: CreateTrainDto) { return this.service.createTrain(dto); }
|
||
|
||
@Get('coaches')
|
||
@ApiOperation({ summary: 'List coaches filtered by status, mode, seat class, or schedule assignment' })
|
||
@ApiQuery({ name: 'isActive', required: false, type: Boolean, description: 'true = active only, false = inactive only, omit = all' })
|
||
@ApiQuery({ name: 'mode', required: false, description: 'Filter by mode: seat | bed | convertible' })
|
||
@ApiQuery({ name: 'seatClassId', required: false, description: 'Filter by SeatClass UUID' })
|
||
@ApiQuery({ name: 'scheduleId', required: false, description: 'Filter to coaches assigned to this TrainSchedule UUID' })
|
||
@ApiResponse({ status: 200, description: 'Coaches with seat class info, assignment count, and seat status summary (total/available/held/booked/blocked)' })
|
||
listCoaches(
|
||
@Query('isActive') isActive?: string,
|
||
@Query('mode') mode?: string,
|
||
@Query('seatClassId') seatClassId?: string,
|
||
@Query('scheduleId') scheduleId?: string,
|
||
) {
|
||
const dto: ListCoachesDto = {
|
||
isActive: isActive === 'true' ? true : isActive === 'false' ? false : undefined,
|
||
mode,
|
||
seatClassId,
|
||
scheduleId,
|
||
};
|
||
return this.service.listCoaches(dto);
|
||
}
|
||
|
||
@Get('coaches/:id')
|
||
@ApiOperation({ summary: 'Get a single coach with full seat layout and arrangement' })
|
||
@ApiParam({ name: 'id', description: 'Coach UUID' })
|
||
@ApiResponse({
|
||
status: 200,
|
||
description: `Coach detail including:
|
||
- seatClass: seat class info
|
||
- seatsByRow: seats grouped by row number, each seat includes label, seatNumber, col, kind (STANDARD/PREMIUM/ACCESSIBLE), status (AVAILABLE/HELD/BOOKED/BLOCKED), isWindow, isAisle, bedPosition (bed mode only), premiumFeeMinor
|
||
- seatStatusSummary: total/available/held/booked/blocked counts
|
||
- assignments: up to 5 most recent schedule assignments with origin/destination`,
|
||
})
|
||
@ApiResponse({ status: 404, description: 'Coach not found' })
|
||
getCoach(@Param('id') id: string) { return this.service.getCoach(id); }
|
||
|
||
@Post('coaches')
|
||
@ApiOperation({ summary: 'Register a new physical coach and auto-generate its seats from arrangement config' })
|
||
@ApiBody({ type: CreateCoachDto })
|
||
@ApiResponse({ status: 201, description: 'Coach created with seats auto-generated from mode + arrangement + totalUnits' })
|
||
@ApiResponse({ status: 400, description: 'Invalid arrangement format' })
|
||
createCoach(@Body() dto: CreateCoachDto) { return this.service.createCoach(dto); }
|
||
|
||
@Patch('coaches/:id')
|
||
@ApiOperation({ summary: 'Update coach properties (label, mode, arrangement, etc.)' })
|
||
@ApiParam({ name: 'id', description: 'Coach UUID' })
|
||
@ApiBody({ type: UpdateCoachDto })
|
||
@ApiResponse({ status: 200, description: 'Coach updated' })
|
||
@ApiResponse({ status: 404, description: 'Coach not found' })
|
||
updateCoach(@Param('id') id: string, @Body() dto: UpdateCoachDto) { return this.service.updateCoach(id, dto); }
|
||
|
||
@Post('assignments')
|
||
@ApiOperation({ summary: 'Assign a physical coach to a train schedule at a given position' })
|
||
@ApiBody({ type: AssignCoachDto })
|
||
@ApiResponse({ status: 201, description: 'CoachAssignment created' })
|
||
@ApiResponse({ status: 404, description: 'Schedule or coach not found' })
|
||
assignCoach(@Body() dto: AssignCoachDto) { return this.service.assignCoach(dto); }
|
||
|
||
@Delete('assignments/:id')
|
||
@ApiOperation({ summary: 'Remove a coach assignment from a schedule' })
|
||
@ApiParam({ name: 'id', description: 'CoachAssignment UUID' })
|
||
@ApiResponse({ status: 200, description: 'Assignment removed' })
|
||
@ApiResponse({ status: 404, description: 'Assignment not found' })
|
||
removeAssignment(@Param('id') id: string) { return this.service.removeAssignment(id); }
|
||
|
||
@Post('seats/batch')
|
||
@ApiOperation({ summary: 'Batch-generate seats for a coach (rows × cols)' })
|
||
@ApiBody({ type: CreateSeatBatchDto })
|
||
@ApiResponse({ status: 201, description: 'Returns count of seats created' })
|
||
@ApiResponse({ status: 404, description: 'Coach not found' })
|
||
createSeatBatch(@Body() dto: CreateSeatBatchDto) { return this.service.createSeatBatch(dto); }
|
||
|
||
@Get('analytics')
|
||
@ApiOperation({ summary: 'Fleet analytics: train count, schedule count, seat occupancy rate' })
|
||
@ApiResponse({ status: 200, description: 'Returns totalTrains, totalSchedules, totalSeats, bookedSeats, occupancyRate' })
|
||
getAnalytics() { return this.service.getAnalytics(); }
|
||
}
|