import { Body, Controller, Get, Param, ParseUUIDPipe, Post, Query, UploadedFile, UseGuards, UseInterceptors, } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { ApiBearerAuth, ApiBody, ApiConsumes, ApiTags } from '@nestjs/swagger'; import { memoryStorage } from 'multer'; import { CurrentUser } from '../auth/decorators/current-user.decorator'; import { Public } from '../auth/decorators/public.decorator'; import { Roles } from '../auth/decorators/roles.decorator'; import { RolesGuard } from '../auth/guards/roles.guard'; import { AuthUser } from '../auth/interfaces/auth-user.interface'; import { ApiStandardController, ApiStandardOkResponse, } from '../swagger/decorators/swagger-response.decorator'; import { ApiPublicEndpoint } from '../swagger/decorators/swagger-auth.decorator'; import { SWAGGER_JWT_AUTH } from '../swagger/swagger.setup'; import { UserRole } from '../users/enums/user-role.enum'; import { CardToCardDepositService } from './card-to-card-deposit.service'; import { DepositListItemDto } from './dto/deposit-list-item.dto'; import { FindDepositsQueryDto } from './dto/find-deposits-query.dto'; import { PublicDepositPaymentDto } from './dto/public-deposit-payment.dto'; import { ReviewDepositDto } from './dto/review-deposit.dto'; import { Payment } from './entities/payment.entity'; const MAX_RECEIPT_SIZE_BYTES = 10 * 1024 * 1024; @ApiTags('Deposits (Card to Card)') @ApiStandardController() @Controller('deposits') export class DepositsController { constructor( private readonly cardToCardDepositService: CardToCardDepositService, ) {} @ApiBearerAuth(SWAGGER_JWT_AUTH) @UseGuards(RolesGuard) @Roles(UserRole.ADMIN, UserRole.SALON) @ApiStandardOkResponse(Payment) @Post('reserves/:reserveId') requestDeposit( @Param('reserveId', ParseUUIDPipe) reserveId: string, @CurrentUser() user: AuthUser, ) { return this.cardToCardDepositService.requestDeposit(reserveId, user); } @Public() @ApiPublicEndpoint('Get card-to-card deposit payment details by public token') @ApiStandardOkResponse(PublicDepositPaymentDto) @Get('public/:token') getPublicPayment(@Param('token') token: string) { return this.cardToCardDepositService.getPublicPaymentByToken(token); } @Public() @ApiPublicEndpoint('Upload the payment receipt for a card-to-card deposit') @ApiConsumes('multipart/form-data') @ApiBody({ schema: { type: 'object', required: ['file'], properties: { file: { type: 'string', format: 'binary' } }, }, }) @ApiStandardOkResponse(PublicDepositPaymentDto) @UseInterceptors( FileInterceptor('file', { storage: memoryStorage(), limits: { fileSize: MAX_RECEIPT_SIZE_BYTES }, }), ) @Post('public/:token/receipt') submitReceipt( @Param('token') token: string, @UploadedFile() file: Express.Multer.File, ) { return this.cardToCardDepositService.submitReceipt(token, file); } @ApiBearerAuth(SWAGGER_JWT_AUTH) @UseGuards(RolesGuard) @Roles(UserRole.ADMIN, UserRole.SALON) @ApiStandardOkResponse(DepositListItemDto, { isArray: true }) @Get() findAll( @Query() query: FindDepositsQueryDto, @CurrentUser() user: AuthUser, ) { return this.cardToCardDepositService.findForSalon(user, query); } @ApiBearerAuth(SWAGGER_JWT_AUTH) @UseGuards(RolesGuard) @Roles(UserRole.ADMIN, UserRole.SALON) @ApiStandardOkResponse(Payment) @Get(':id') findForReview( @Param('id', ParseUUIDPipe) id: string, @CurrentUser() user: AuthUser, ) { return this.cardToCardDepositService.findForReview(id, user); } @ApiBearerAuth(SWAGGER_JWT_AUTH) @UseGuards(RolesGuard) @Roles(UserRole.ADMIN, UserRole.SALON) @ApiStandardOkResponse(Payment) @Post(':id/review') review( @Param('id', ParseUUIDPipe) id: string, @Body() dto: ReviewDepositDto, @CurrentUser() user: AuthUser, ) { return this.cardToCardDepositService.reviewDeposit(id, dto, user); } }