177 lines
6.2 KiB
TypeScript
177 lines
6.2 KiB
TypeScript
import { Controller, Get, Post, Param, Query, Body } from '@nestjs/common';
|
|
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery, ApiBody } from '@nestjs/swagger';
|
|
import { Public } from '../decorators/public.decorator';
|
|
import { CsvBookingService } from '../services/csv-booking.service';
|
|
import {
|
|
CarrierDocumentsResponseDto,
|
|
VerifyDocumentAccessDto,
|
|
DocumentAccessRequirementsDto,
|
|
} from '../dto/carrier-documents.dto';
|
|
|
|
/**
|
|
* 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,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Check document access requirements (PUBLIC - token-based)
|
|
*
|
|
* GET /api/v1/csv-booking-actions/documents/:token/requirements
|
|
*/
|
|
@Public()
|
|
@Get('documents/:token/requirements')
|
|
@ApiOperation({
|
|
summary: 'Check document access requirements (public)',
|
|
description:
|
|
'Check if a password is required to access booking documents. Use this before showing the password form.',
|
|
})
|
|
@ApiParam({ name: 'token', description: 'Booking confirmation token (UUID)' })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: 'Access requirements retrieved successfully.',
|
|
type: DocumentAccessRequirementsDto,
|
|
})
|
|
@ApiResponse({ status: 404, description: 'Booking not found or invalid token' })
|
|
async getDocumentAccessRequirements(
|
|
@Param('token') token: string
|
|
): Promise<DocumentAccessRequirementsDto> {
|
|
return this.csvBookingService.checkDocumentAccessRequirements(token);
|
|
}
|
|
|
|
/**
|
|
* Get booking documents for carrier with password verification (PUBLIC - token-based)
|
|
*
|
|
* POST /api/v1/csv-booking-actions/documents/:token
|
|
*/
|
|
@Public()
|
|
@Post('documents/:token')
|
|
@ApiOperation({
|
|
summary: 'Get booking documents with password (public)',
|
|
description:
|
|
'Public endpoint for carriers to access booking documents after acceptance. Requires password verification. Returns booking summary and documents with signed download URLs.',
|
|
})
|
|
@ApiParam({ name: 'token', description: 'Booking confirmation token (UUID)' })
|
|
@ApiBody({ type: VerifyDocumentAccessDto })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: 'Booking documents retrieved successfully.',
|
|
type: CarrierDocumentsResponseDto,
|
|
})
|
|
@ApiResponse({ status: 404, description: 'Booking not found or invalid token' })
|
|
@ApiResponse({ status: 400, description: 'Booking has not been accepted yet' })
|
|
@ApiResponse({ status: 401, description: 'Invalid password' })
|
|
async getBookingDocumentsWithPassword(
|
|
@Param('token') token: string,
|
|
@Body() dto: VerifyDocumentAccessDto
|
|
): Promise<CarrierDocumentsResponseDto> {
|
|
return this.csvBookingService.getDocumentsForCarrier(token, dto.password);
|
|
}
|
|
|
|
/**
|
|
* Get booking documents for carrier (PUBLIC - token-based) - Legacy without password
|
|
* Kept for backward compatibility with bookings created before password protection
|
|
*
|
|
* GET /api/v1/csv-booking-actions/documents/:token
|
|
*/
|
|
@Public()
|
|
@Get('documents/:token')
|
|
@ApiOperation({
|
|
summary: 'Get booking documents (public) - Legacy',
|
|
description:
|
|
'Public endpoint for carriers to access booking documents. For new bookings, use POST with password instead.',
|
|
})
|
|
@ApiParam({ name: 'token', description: 'Booking confirmation token (UUID)' })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: 'Booking documents retrieved successfully.',
|
|
type: CarrierDocumentsResponseDto,
|
|
})
|
|
@ApiResponse({ status: 404, description: 'Booking not found or invalid token' })
|
|
@ApiResponse({ status: 400, description: 'Booking has not been accepted yet' })
|
|
@ApiResponse({ status: 401, description: 'Password required for this booking' })
|
|
async getBookingDocuments(@Param('token') token: string): Promise<CarrierDocumentsResponseDto> {
|
|
return this.csvBookingService.getDocumentsForCarrier(token);
|
|
}
|
|
}
|