import { Body, Controller, Delete, Get, Param, Patch, Post, Query, UseGuards } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'; import { IsInt, IsPositive, IsString } from 'class-validator'; import { ExcessBaggageService } from './excess-baggage.service'; import { LogExcessBaggageDto, WaiveChargeDto, InitiateExcessPaymentDto, } from './excess-baggage.dto'; import { JwtGuard as IamJwtGuard } from '@tria-plc/api-common/modules/auth/services/jwt.guard'; class UpsertBaggageAllowanceDto { @IsString() seatClassId: string; @IsInt() @IsPositive() maxWeightKg: number; @IsInt() @IsPositive() maxPiecesCount: number; @IsInt() @IsPositive() excessFeePerKg: number; } // ── IAM-protected agent/supervisor routes ──────────────────────────────────── @ApiTags('Excess Baggage') @Controller('agents/excess-baggage') @UseGuards(IamJwtGuard) @ApiBearerAuth('IAM-auth') export class ExcessBaggageAgentController { constructor(private service: ExcessBaggageService) {} @Post() @ApiOperation({ summary: 'Log excess baggage charge and optionally collect cash' }) logCharge(@Body() dto: LogExcessBaggageDto) { return this.service.logCharge(dto); } @Get() @ApiOperation({ summary: 'List all excess baggage charges (admin/supervisor)' }) getAll( @Query('status') status?: string, @Query('bookingRef') bookingRef?: string, @Query('dateFrom') dateFrom?: string, @Query('dateTo') dateTo?: string, @Query('page') page?: string, @Query('pageSize') pageSize?: string, ) { return this.service.getAll({ status, bookingRef, dateFrom, dateTo, page: page ? parseInt(page) : undefined, pageSize: pageSize ? parseInt(pageSize) : undefined, }); } @Get(':id') @ApiOperation({ summary: 'Get a single charge by ID (agent polling)' }) getCharge(@Param('id') id: string) { return this.service.getCharge(id); } @Post(':id/resend') @ApiOperation({ summary: 'Resend payment link (extends expiry by 30 min)' }) resendLink(@Param('id') id: string) { return this.service.resendLink(id); } @Patch(':id/waive') @ApiOperation({ summary: 'Waive a charge (supervisor only)' }) waiveCharge(@Param('id') id: string, @Body() dto: WaiveChargeDto) { return this.service.waiveCharge(id, dto); } @Get('allowances') @ApiOperation({ summary: 'List all baggage allowance rules' }) getAllowances() { return this.service.getAllowances(); } @Post('allowances') @ApiOperation({ summary: 'Create baggage allowance rule for a seat class' }) createAllowance(@Body() dto: UpsertBaggageAllowanceDto) { return this.service.upsertAllowance(dto); } @Patch('allowances/:id') @ApiOperation({ summary: 'Update baggage allowance rule' }) updateAllowance(@Param('id') id: string, @Body() dto: Partial) { return this.service.updateAllowance(id, dto); } @Delete('allowances/:id') @ApiOperation({ summary: 'Delete baggage allowance rule' }) deleteAllowance(@Param('id') id: string) { return this.service.deleteAllowance(id); } } // ── Public pay-by-token routes (passenger self-service) ────────────────────── @ApiTags('Excess Baggage') @Controller('excess-baggage') export class ExcessBaggagePublicController { constructor(private service: ExcessBaggageService) {} @Get('pay/:token') @ApiOperation({ summary: 'Retrieve charge details by payment token (public)' }) getByToken(@Param('token') token: string) { return this.service.getByToken(token); } @Post('pay/:token/initiate') @ApiOperation({ summary: 'Passenger initiates payment for excess baggage charge' }) initiatePayment( @Param('token') token: string, @Body() dto: InitiateExcessPaymentDto, ) { return this.service.initiatePayment(token, dto); } }