diff --git a/apps/edr-passenger-api/src/modules/bookings/bookings.dto.ts b/apps/edr-passenger-api/src/modules/bookings/bookings.dto.ts index 6e45aeab4..345cfc357 100644 --- a/apps/edr-passenger-api/src/modules/bookings/bookings.dto.ts +++ b/apps/edr-passenger-api/src/modules/bookings/bookings.dto.ts @@ -4,7 +4,7 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Currency, IdDocumentType } from '@prisma/client'; export class PassengerInputDto { - @ApiProperty({ example: 'seat-uuid', description: 'Outbound / leg-1 seat ID (all booking types)' }) @IsString() seatId: string; + @ApiPropertyOptional({ example: 'seat-uuid', description: 'Outbound / leg-1 seat ID (all booking types). Omit for free children (package bookings) — backend auto-assigns.' }) @IsOptional() @IsString() seatId?: string; @ApiPropertyOptional({ example: 'leg2-seat-uuid', description: '**TRANSIT / ROUND_TRIP_TRANSIT:** Outbound leg-2 seat ID' }) @IsOptional() @IsString() leg2SeatId?: string; @ApiPropertyOptional({ example: 'return-seat-uuid', description: '**ROUND_TRIP / ROUND_TRIP_TRANSIT:** Return leg-1 seat ID' }) @IsOptional() @IsString() returnSeatId?: string; @ApiPropertyOptional({ example: 'ret-leg2-seat-uuid', description: '**ROUND_TRIP_TRANSIT:** Return leg-2 seat ID' }) @IsOptional() @IsString() returnLeg2SeatId?: string; @@ -24,11 +24,11 @@ export class PassengerInputDto { } export class RoundTripPassengerDto { - @ApiProperty({ description: 'Outbound journey seat ID', example: 'seat-uuid-outbound' }) - @IsString() outboundSeatId: string; + @ApiPropertyOptional({ description: 'Outbound journey seat ID', example: 'seat-uuid-outbound' }) + @IsOptional() @IsString() outboundSeatId?: string; - @ApiProperty({ description: 'Return journey seat ID', example: 'seat-uuid-return' }) - @IsString() returnSeatId: string; + @ApiPropertyOptional({ description: 'Return journey seat ID', example: 'seat-uuid-return' }) + @IsOptional() @IsString() returnSeatId?: string; @ApiPropertyOptional({ description: '**ROUND_TRIP_TRANSIT:** Outbound leg-2 seat ID' }) @IsOptional() @IsString() outboundLeg2SeatId?: string; diff --git a/apps/edr-passenger-api/src/modules/bookings/guest-booking.dto.ts b/apps/edr-passenger-api/src/modules/bookings/guest-booking.dto.ts index c6f27d9c3..c2acaeece 100644 --- a/apps/edr-passenger-api/src/modules/bookings/guest-booking.dto.ts +++ b/apps/edr-passenger-api/src/modules/bookings/guest-booking.dto.ts @@ -4,8 +4,8 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Currency, IdDocumentType } from '@prisma/client'; export class GuestPassengerDto { - @ApiProperty({ example: 'seat-uuid', description: 'Outbound / leg-1 seat ID (all booking types)' }) - @IsString() seatId: string; + @ApiPropertyOptional({ example: 'seat-uuid', description: 'Outbound / leg-1 seat ID (all booking types). Omit for free children (package bookings) — backend auto-assigns.' }) + @IsOptional() @IsString() seatId?: string; @ApiPropertyOptional({ example: 'return-seat-uuid', description: '**ROUND_TRIP / ROUND_TRIP_TRANSIT:** Return leg-1 seat ID. Required for ROUND_TRIP and ROUND_TRIP_TRANSIT.' }) @IsOptional() @IsString() returnSeatId?: string; diff --git a/apps/edr-passenger-api/src/modules/bookings/guest-booking.service.ts b/apps/edr-passenger-api/src/modules/bookings/guest-booking.service.ts index f4139d842..1025a42b3 100644 --- a/apps/edr-passenger-api/src/modules/bookings/guest-booking.service.ts +++ b/apps/edr-passenger-api/src/modules/bookings/guest-booking.service.ts @@ -260,7 +260,7 @@ export class GuestBookingService { await this.createTravelerProfiles(guestPassengerId, passengersData); // Confirm seats - await this.seatsService.confirmSeats(dto.passengers.map(p => p.seatId)); + await this.seatsService.confirmSeats(dto.passengers.map(p => p.seatId).filter((id): id is string => !!id)); this.eventEmitter.emit('booking.created', { booking }); return { @@ -434,7 +434,7 @@ export class GuestBookingService { const { guestPassengerId, iamUserId, createdAccount } = await this.resolveGuestPassenger(dto, passengersData[0], req); // Create booking with outbound seats; return seats confirmed separately - const outboundSeatIds = dto.passengers.map(p => p.seatId); + const outboundSeatIds = dto.passengers.map(p => p.seatId).filter((id): id is string => !!id); const returnSeatIds = dto.passengers.map(p => p.returnSeatId!); const booking = await this.prisma.booking.create({ @@ -701,7 +701,7 @@ export class GuestBookingService { await this.createTravelerProfiles(guestPassengerId, passengersData); await Promise.all([ - this.seatsService.confirmSeats(dto.passengers.map(p => p.seatId)), + this.seatsService.confirmSeats(dto.passengers.map(p => p.seatId).filter((id): id is string => !!id)), this.seatsService.confirmSeats(dto.passengers.map(p => p.leg2SeatId!)), ]); this.eventEmitter.emit('booking.created', { booking }); @@ -894,7 +894,7 @@ export class GuestBookingService { await this.createTravelerProfiles(guestPassengerId, passengersData); await Promise.all([ - this.seatsService.confirmSeats(dto.passengers.map(p => p.seatId)), + this.seatsService.confirmSeats(dto.passengers.map(p => p.seatId).filter((id): id is string => !!id)), this.seatsService.confirmSeats(dto.passengers.map(p => p.leg2SeatId!)), this.seatsService.confirmSeats(dto.passengers.map(p => p.returnSeatId!)), this.seatsService.confirmSeats(dto.passengers.map(p => p.returnLeg2SeatId!)),