mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 08:20:58 +00:00
Updated seat class and coach mangement
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Body, Controller, Delete, Get, Param, Post, Query, UseGuards } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';
|
||||
import { SeatsService } from './seats.service';
|
||||
import { HoldSeatsDto } from './seats.dto';
|
||||
import { JwtGuard } from '../../common/jwt.guard';
|
||||
@@ -8,10 +8,28 @@ import { JwtGuard } from '../../common/jwt.guard';
|
||||
@Controller('seats')
|
||||
export class SeatsController {
|
||||
constructor(private service: SeatsService) {}
|
||||
@Get('seatmap/:tripId') @ApiOperation({ summary: 'Get seat map for a trip' })
|
||||
|
||||
// ── Seat Map ──────────────────────────────────────────────────────────────
|
||||
@Get('seatmap/:tripId')
|
||||
@ApiOperation({ summary: 'Get seat map for a trip' })
|
||||
@ApiParam({ name: 'tripId', description: 'Trip UUID' })
|
||||
@ApiQuery({ name: 'coachId', required: false, description: 'Filter by coach UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Returns coaches with seats and seat class info' })
|
||||
getSeatMap(@Param('tripId') tripId: string, @Query('coachId') coachId?: string) { return this.service.getSeatMap(tripId, coachId); }
|
||||
@Post('hold') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Hold seats for 15 minutes' })
|
||||
|
||||
// ── Hold / Release ────────────────────────────────────────────────────────
|
||||
@Post('hold')
|
||||
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
|
||||
@ApiOperation({ summary: 'Hold seats for 15 minutes' })
|
||||
@ApiResponse({ status: 201, description: 'Seats held successfully' })
|
||||
@ApiResponse({ status: 409, description: 'One or more seats unavailable' })
|
||||
holdSeats(@Body() dto: HoldSeatsDto) { return this.service.holdSeats(dto); }
|
||||
@Delete('hold/:holdId') @UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @ApiOperation({ summary: 'Release a seat hold' })
|
||||
|
||||
@Delete('hold/:holdId')
|
||||
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
|
||||
@ApiOperation({ summary: 'Release a seat hold' })
|
||||
@ApiParam({ name: 'holdId', description: 'Hold UUID' })
|
||||
@ApiResponse({ status: 200, description: 'Hold released' })
|
||||
@ApiResponse({ status: 404, description: 'Hold not found' })
|
||||
releaseHold(@Param('holdId') holdId: string) { return this.service.releaseHold(holdId); }
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { IsString, IsArray } from 'class-validator';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsString, IsArray, IsOptional } from 'class-validator';
|
||||
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class HoldSeatsDto {
|
||||
@ApiProperty() @IsString() tripId: string;
|
||||
@ApiProperty() @IsString() passengerId: string;
|
||||
@ApiProperty({ type: [String] }) @IsArray() seatIds: string[];
|
||||
@ApiProperty({ required: false }) fareQuoteId?: string;
|
||||
@ApiProperty({ example: 'trip-uuid' }) @IsString() tripId: string;
|
||||
@ApiProperty({ example: 'passenger-uuid' }) @IsString() passengerId: string;
|
||||
@ApiProperty({ type: [String], example: ['seat-uuid-1', 'seat-uuid-2'] }) @IsArray() seatIds: string[];
|
||||
@ApiPropertyOptional({ example: 'fare-quote-uuid' }) @IsOptional() @IsString() fareQuoteId?: string;
|
||||
}
|
||||
|
||||
@@ -7,18 +7,20 @@ import { Cron, CronExpression } from '@nestjs/schedule';
|
||||
export class SeatsService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
// ── Seat Map ──────────────────────────────────────────────────────────────
|
||||
async getSeatMap(tripId: string, coachId?: string) {
|
||||
const coaches = await this.prisma.coach.findMany({ where: { tripId, ...(coachId ? { id: coachId } : {}) }, include: { seats: { orderBy: [{ row: 'asc' }, { col: 'asc' }] } } });
|
||||
const coaches = await this.prisma.coach.findMany({ where: { tripId, ...(coachId ? { id: coachId } : {}) }, include: { seatClass: true, seats: { orderBy: [{ row: 'asc' }, { col: 'asc' }] } } });
|
||||
return {
|
||||
coaches: coaches.map((coach) => ({
|
||||
id: coach.id,
|
||||
name: `Coach ${coach.label}`,
|
||||
type: coach.serviceClass,
|
||||
seatClass: { id: coach.seatClass.id, name: coach.seatClass.name, basePrice: coach.seatClass.basePrice },
|
||||
seats: coach.seats.map((s) => ({ id: s.id, number: s.label, status: s.status, kind: s.kind })),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
// ── Hold / Release ────────────────────────────────────────────────────────
|
||||
async holdSeats(dto: HoldSeatsDto) {
|
||||
const expiresAt = new Date(Date.now() + 15 * 60 * 1000);
|
||||
const hold = await this.prisma.$transaction(async (tx) => {
|
||||
|
||||
Reference in New Issue
Block a user