import { Controller, Get, Param, Query } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery } from '@nestjs/swagger'; import { Public } from '../decorators/public.decorator'; import { CsvBookingService } from '../services/csv-booking.service'; /** * CSV Booking Actions Controller (Public Routes) * * Handles public accept/reject actions from carrier emails * Separated from main controller to avoid routing conflicts */ @ApiTags('CSV Booking Actions') @Controller('csv-booking-actions') export class CsvBookingActionsController { constructor(private readonly csvBookingService: CsvBookingService) {} /** * Accept a booking request (PUBLIC - token-based) * * GET /api/v1/csv-booking-actions/accept/:token */ @Public() @Get('accept/:token') @ApiOperation({ summary: 'Accept booking request (public)', description: 'Public endpoint for carriers to accept a booking via email link. Updates booking status and notifies the user.', }) @ApiParam({ name: 'token', description: 'Booking confirmation token (UUID)' }) @ApiResponse({ status: 200, description: 'Booking accepted successfully.', }) @ApiResponse({ status: 404, description: 'Booking not found or invalid token' }) @ApiResponse({ status: 400, description: 'Booking cannot be accepted (invalid status or expired)', }) async acceptBooking(@Param('token') token: string) { // Accept the booking const booking = await this.csvBookingService.acceptBooking(token); // Return simple success response return { success: true, bookingId: booking.id, action: 'accepted', }; } /** * Reject a booking request (PUBLIC - token-based) * * GET /api/v1/csv-booking-actions/reject/:token */ @Public() @Get('reject/:token') @ApiOperation({ summary: 'Reject booking request (public)', description: 'Public endpoint for carriers to reject a booking via email link. Updates booking status and notifies the user.', }) @ApiParam({ name: 'token', description: 'Booking confirmation token (UUID)' }) @ApiQuery({ name: 'reason', required: false, description: 'Rejection reason', example: 'No capacity available', }) @ApiResponse({ status: 200, description: 'Booking rejected successfully.', }) @ApiResponse({ status: 404, description: 'Booking not found or invalid token' }) @ApiResponse({ status: 400, description: 'Booking cannot be rejected (invalid status or expired)', }) async rejectBooking(@Param('token') token: string, @Query('reason') reason: string) { // Reject the booking const booking = await this.csvBookingService.rejectBooking(token, reason); // Return simple success response return { success: true, bookingId: booking.id, action: 'rejected', reason: reason || null, }; } }