mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-28 11:21:18 +00:00
Coaches, seats, schedules, and pricing related updates
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
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 { CreateTrainDto, CreateCoachDto, UpdateCoachDto, AssignCoachDto, ListCoachesDto, CreateCoachTypeDto, UpdateCoachTypeDto, CreateClassDto, UpdateClassDto } from './fleet.dto';
|
||||
import { JwtGuard } from '../../common/jwt.guard';
|
||||
|
||||
@ApiTags('Fleet')
|
||||
@@ -11,16 +11,128 @@ import { JwtGuard } from '../../common/jwt.guard';
|
||||
export class FleetController {
|
||||
constructor(private service: FleetService) {}
|
||||
|
||||
// Coach Type Endpoints
|
||||
@Get('coach-types')
|
||||
@ApiOperation({ summary: 'List all coach types' })
|
||||
@ApiResponse({ status: 200, description: 'Array of coach types' })
|
||||
getCoachTypes() {
|
||||
return this.service.getCoachTypes();
|
||||
}
|
||||
|
||||
@Post('coach-types')
|
||||
@ApiOperation({ summary: 'Create a coach type' })
|
||||
@ApiBody({ type: CreateCoachTypeDto })
|
||||
@ApiResponse({ status: 201, description: 'Coach type created' })
|
||||
createCoachType(@Body() dto: CreateCoachTypeDto) {
|
||||
return this.service.createCoachType(dto);
|
||||
}
|
||||
|
||||
@Patch('coach-types/:id')
|
||||
@ApiOperation({ summary: 'Update a coach type' })
|
||||
@ApiParam({ name: 'id', description: 'Coach Type UUID' })
|
||||
@ApiBody({ type: UpdateCoachTypeDto })
|
||||
@ApiResponse({ status: 200, description: 'Coach type updated' })
|
||||
@ApiResponse({ status: 404, description: 'Coach type not found' })
|
||||
updateCoachType(@Param('id') id: string, @Body() dto: UpdateCoachTypeDto) {
|
||||
return this.service.updateCoachType(id, dto);
|
||||
}
|
||||
|
||||
@Delete('coach-types/:id')
|
||||
@ApiOperation({ summary: 'Delete a coach type' })
|
||||
@ApiParam({ name: 'id', description: 'Coach Type UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Coach type deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Coach type not found' })
|
||||
deleteCoachType(@Param('id') id: string) {
|
||||
return this.service.deleteCoachType(id);
|
||||
}
|
||||
|
||||
// Class Endpoints
|
||||
@Get('classes')
|
||||
@ApiOperation({ summary: 'List all classes' })
|
||||
@ApiQuery({ name: 'coachTypeId', required: false, description: 'Filter by coach type' })
|
||||
@ApiResponse({ status: 200, description: 'Array of classes' })
|
||||
getClasses(@Query('coachTypeId') coachTypeId?: string) {
|
||||
return this.service.getClasses(coachTypeId);
|
||||
}
|
||||
|
||||
@Post('classes')
|
||||
@ApiOperation({ summary: 'Create a class' })
|
||||
@ApiBody({ type: CreateClassDto })
|
||||
@ApiResponse({ status: 201, description: 'Class created' })
|
||||
createClass(@Body() dto: CreateClassDto) {
|
||||
return this.service.createClass(dto);
|
||||
}
|
||||
|
||||
@Patch('classes/:id')
|
||||
@ApiOperation({ summary: 'Update a class' })
|
||||
@ApiParam({ name: 'id', description: 'Class UUID' })
|
||||
@ApiBody({ type: UpdateClassDto })
|
||||
@ApiResponse({ status: 200, description: 'Class updated' })
|
||||
@ApiResponse({ status: 404, description: 'Class not found' })
|
||||
updateClass(@Param('id') id: string, @Body() dto: UpdateClassDto) {
|
||||
return this.service.updateClass(id, dto);
|
||||
}
|
||||
|
||||
@Delete('classes/:id')
|
||||
@ApiOperation({ summary: 'Delete a class' })
|
||||
@ApiParam({ name: 'id', description: 'Class UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Class deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Class not found' })
|
||||
deleteClass(@Param('id') id: string) {
|
||||
return this.service.deleteClass(id);
|
||||
}
|
||||
|
||||
// Seat Class Endpoints (DEPRECATED - use Classes endpoints instead)
|
||||
@Get('seat-classes')
|
||||
@ApiOperation({ summary: 'List all classes (DEPRECATED - use /fleet/classes)' })
|
||||
@ApiQuery({ name: 'coachTypeId', required: false, description: 'Filter by coach type' })
|
||||
@ApiResponse({ status: 200, description: 'Array of classes' })
|
||||
getSeatClasses(@Query('coachTypeId') coachTypeId?: string) {
|
||||
return this.service.getClasses(coachTypeId);
|
||||
}
|
||||
|
||||
@Post('seat-classes')
|
||||
@ApiOperation({ summary: 'Create a class (DEPRECATED - use /fleet/classes)' })
|
||||
@ApiBody({ type: CreateClassDto })
|
||||
@ApiResponse({ status: 201, description: 'Class created' })
|
||||
createSeatClass(@Body() dto: CreateClassDto) {
|
||||
return this.service.createClass(dto);
|
||||
}
|
||||
|
||||
@Patch('seat-classes/:id')
|
||||
@ApiOperation({ summary: 'Update a class (DEPRECATED - use /fleet/classes)' })
|
||||
@ApiParam({ name: 'id', description: 'Class UUID' })
|
||||
@ApiBody({ type: UpdateClassDto })
|
||||
@ApiResponse({ status: 200, description: 'Class updated' })
|
||||
@ApiResponse({ status: 404, description: 'Class not found' })
|
||||
updateSeatClass(@Param('id') id: string, @Body() dto: UpdateClassDto) {
|
||||
return this.service.updateClass(id, dto);
|
||||
}
|
||||
|
||||
@Delete('seat-classes/:id')
|
||||
@ApiOperation({ summary: 'Delete a class (DEPRECATED - use /fleet/classes)' })
|
||||
@ApiParam({ name: 'id', description: 'Class UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Class deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Class not found' })
|
||||
deleteSeatClass(@Param('id') id: string) {
|
||||
return this.service.deleteClass(id);
|
||||
}
|
||||
|
||||
// Train Endpoints
|
||||
@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(); }
|
||||
@ApiResponse({ status: 200, description: 'Array of trains' })
|
||||
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); }
|
||||
createTrain(@Body() dto: CreateTrainDto) {
|
||||
return this.service.createTrain(dto);
|
||||
}
|
||||
|
||||
@Patch('trains/:id')
|
||||
@ApiOperation({ summary: 'Update a train service' })
|
||||
@@ -28,96 +140,95 @@ export class FleetController {
|
||||
@ApiBody({ type: CreateTrainDto })
|
||||
@ApiResponse({ status: 200, description: 'Train updated' })
|
||||
@ApiResponse({ status: 404, description: 'Train not found' })
|
||||
updateTrain(@Param('id') id: string, @Body() dto: CreateTrainDto) { return this.service.updateTrain(id, 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);
|
||||
updateTrain(@Param('id') id: string, @Body() dto: CreateTrainDto) {
|
||||
return this.service.updateTrain(id, 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); }
|
||||
|
||||
@Delete('trains/:id')
|
||||
@ApiOperation({ summary: 'Delete a train service' })
|
||||
@ApiParam({ name: 'id', description: 'Train UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Train deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Train not found' })
|
||||
deleteTrain(@Param('id') id: string) { return this.service.deleteTrain(id); }
|
||||
deleteTrain(@Param('id') id: string) {
|
||||
return this.service.deleteTrain(id);
|
||||
}
|
||||
|
||||
// Coach Endpoints
|
||||
@Get('coaches')
|
||||
@ApiOperation({ summary: 'List coaches with seat status summary' })
|
||||
@ApiQuery({ name: 'status', required: false, description: 'Filter by status: ACTIVE, INACTIVE' })
|
||||
@ApiQuery({ name: 'scheduleId', required: false, description: 'Filter coaches assigned to schedule' })
|
||||
@ApiResponse({ status: 200, description: 'Array of coaches' })
|
||||
listCoaches(
|
||||
@Query('status') status?: string,
|
||||
@Query('scheduleId') scheduleId?: string,
|
||||
) {
|
||||
const dto: ListCoachesDto = {
|
||||
status,
|
||||
scheduleId,
|
||||
};
|
||||
return this.service.listCoaches(dto);
|
||||
}
|
||||
|
||||
@Get('coaches/:id')
|
||||
@ApiOperation({ summary: 'Get single coach with seat layout' })
|
||||
@ApiParam({ name: 'id', description: 'Coach UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Coach detail with seats by row' })
|
||||
@ApiResponse({ status: 404, description: 'Coach not found' })
|
||||
getCoach(@Param('id') id: string) {
|
||||
return this.service.getCoach(id);
|
||||
}
|
||||
|
||||
@Post('coaches')
|
||||
@ApiOperation({ summary: 'Create a coach with auto-generated seat numbers' })
|
||||
@ApiBody({ type: CreateCoachDto })
|
||||
@ApiResponse({ status: 201, description: 'Coach created' })
|
||||
@ApiResponse({ status: 400, description: 'Invalid arrangement format' })
|
||||
createCoach(@Body() dto: CreateCoachDto) {
|
||||
return this.service.createCoach(dto);
|
||||
}
|
||||
|
||||
@Patch('coaches/:id')
|
||||
@ApiOperation({ summary: 'Update coach properties' })
|
||||
@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);
|
||||
}
|
||||
|
||||
@Delete('coaches/:id')
|
||||
@ApiOperation({ summary: 'Delete a coach' })
|
||||
@ApiParam({ name: 'id', description: 'Coach UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Coach deleted' })
|
||||
@ApiResponse({ status: 404, description: 'Coach not found' })
|
||||
deleteCoach(@Param('id') id: string) { return this.service.deleteCoach(id); }
|
||||
deleteCoach(@Param('id') id: string) {
|
||||
return this.service.deleteCoach(id);
|
||||
}
|
||||
|
||||
@Post('assignments')
|
||||
@ApiOperation({ summary: 'Assign a physical coach to a train schedule at a given position' })
|
||||
@ApiOperation({ summary: 'Assign a coach to a schedule' })
|
||||
@ApiBody({ type: AssignCoachDto })
|
||||
@ApiResponse({ status: 201, description: 'CoachAssignment created' })
|
||||
@ApiResponse({ status: 201, description: 'Coach assigned' })
|
||||
@ApiResponse({ status: 404, description: 'Schedule or coach not found' })
|
||||
assignCoach(@Body() dto: AssignCoachDto) { return this.service.assignCoach(dto); }
|
||||
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' })
|
||||
@ApiOperation({ summary: 'Remove a coach assignment' })
|
||||
@ApiParam({ name: 'id', description: 'Assignment 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); }
|
||||
removeAssignment(@Param('id') id: string) {
|
||||
return this.service.removeAssignment(id);
|
||||
}
|
||||
|
||||
@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(); }
|
||||
@ApiOperation({ summary: 'Fleet analytics and occupancy metrics' })
|
||||
@ApiResponse({ status: 200, description: 'Occupancy statistics' })
|
||||
getAnalytics() {
|
||||
return this.service.getAnalytics();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user