import { Controller, Get, UseGuards, Patch, Body, ValidationPipe, Post, Query, Delete, Param } from '@nestjs/common'; import { ApiTags, ApiBearerAuth, ApiOperation, ApiBody, ApiOkResponse, ApiHeader } from '@nestjs/swagger'; import { AuthGuard } from 'src/modules/auth/guards/auth.guard'; import { UserService } from '../providers/user.service'; import { UpdateUserDto } from '../dto/update-user.dto'; import { CreateUserAddressDto } from '../dto/create-user-address.dto'; import { UpdateUserAddressDto } from '../dto/update-user-address.dto'; import { UserId } from 'src/common/decorators/user-id.decorator'; import { RestId } from 'src/common/decorators'; import { FindUsersDto } from '../dto/find-user.dto'; import { FindWalletTransactionsDto } from '../dto/find-wallet-transactions.dto'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; import { API_HEADER_SLUG } from 'src/common/constants/index'; import { UserSuccessMessage } from 'src/common/enums/message.enum'; import { Permissions } from 'src/common/decorators/permissions.decorator'; import { Permission } from 'src/common/enums/permission.enum'; @ApiTags('User') @Controller() export class UsersController { constructor(private readonly userService: UserService) { } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Get the current authenticated user profile' }) @ApiHeader(API_HEADER_SLUG) @Get('public/user/me') async getUser(@UserId() userId: string) { const user = await this.userService.findById(userId); return user; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Update the authenticated user profile' }) @ApiHeader(API_HEADER_SLUG) @ApiBody({ type: UpdateUserDto }) @Patch('public/user/update') async updateUser(@UserId() userId: string, @RestId() restId: string, @Body() dto: UpdateUserDto) { const user = await this.userService.updateUser(userId, restId, dto); return user; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Get all addresses for the authenticated user' }) @ApiHeader(API_HEADER_SLUG) @ApiOkResponse({ description: 'List of user addresses' }) @Get('public/user/addresses') async getUserAddresses(@UserId() userId: string) { const addresses = await this.userService.getUserAddresses(userId); return addresses; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Get User Wallet' }) @ApiHeader(API_HEADER_SLUG) @Get('public/user/wallet') async getUserWallet(@UserId() userId: string, @RestId() restId: string) { const wallet = await this.userService.getUserWallet(userId, restId); return wallet; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Get User Wallet Transactions' }) @ApiHeader(API_HEADER_SLUG) @Get('public/user/wallet/transactions') async getUserWalletTransactions( @UserId() userId: string, @RestId() restId: string, @Query(new ValidationPipe({ transform: true, whitelist: true })) query: FindWalletTransactionsDto, ) { const transactions = await this.userService.getUserWalletTransactions(userId, restId, query); return transactions; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Create a new address for the authenticated user' }) @ApiHeader(API_HEADER_SLUG) @ApiBody({ type: CreateUserAddressDto }) @ApiOkResponse({ description: 'Created user address' }) @Post('public/user/addresses') async createUserAddress( @UserId() userId: string, @Body(new ValidationPipe({ transform: true, whitelist: true })) dto: CreateUserAddressDto, ) { const address = await this.userService.createUserAddress(userId, dto); return address; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Get a single address by ID for the authenticated user' }) @ApiHeader(API_HEADER_SLUG) @ApiOkResponse({ description: 'User address details' }) @Get('public/user/addresses/:addressId') async getUserAddress(@UserId() userId: string, @Param('addressId') addressId: string) { const address = await this.userService.getUserAddress(userId, addressId); return address; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Update an address for the authenticated user' }) @ApiHeader(API_HEADER_SLUG) @ApiBody({ type: UpdateUserAddressDto }) @ApiOkResponse({ description: 'Updated user address' }) @Patch('public/user/addresses/:addressId') async updateUserAddress( @UserId() userId: string, @Param('addressId') addressId: string, @Body(new ValidationPipe({ transform: true, whitelist: true })) dto: UpdateUserAddressDto, ) { const address = await this.userService.updateUserAddress(userId, addressId, dto); return address; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Delete an address for the authenticated user' }) @ApiHeader(API_HEADER_SLUG) @ApiOkResponse({ description: 'Address deleted successfully' }) @Delete('public/user/addresses/:addressId') async deleteUserAddress(@UserId() userId: string, @Param('addressId') addressId: string) { await this.userService.deleteUserAddress(userId, addressId); return { message: UserSuccessMessage.ADDRESS_DELETED_SUCCESS }; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Set an address as default for the authenticated user' }) @ApiHeader(API_HEADER_SLUG) @ApiOkResponse({ description: 'Address set as default' }) @Patch('public/user/addresses/:addressId/default') async setDefaultAddress(@UserId() userId: string, @Param('addressId') addressId: string) { const address = await this.userService.setDefaultAddress(userId, addressId); return address; } @UseGuards(AuthGuard) @ApiBearerAuth() @ApiOperation({ summary: 'Convert user score (points) to wallet balance' }) @ApiHeader(API_HEADER_SLUG) @Post('public/user/convert-score-to-wallet') async convertScoreToWallet(@UserId() userId: string, @RestId() restId: string) { await this.userService.convertScoreToWallet(userId, restId); return { message: UserSuccessMessage.SCORE_CONVERTED_SUCCESS, }; } /******************** Admin Routes **********************/ @UseGuards(AdminAuthGuard) @ApiBearerAuth() @Permissions(Permission.MANAGE_USERS) @ApiOperation({ summary: 'Get paginated list of restuarant users with filters' }) @Get('admin/users') async findAllRestaurantUsers( @Query(new ValidationPipe({ transform: true, whitelist: true })) query: FindUsersDto, @RestId() restId: string, ) { return this.userService.findAll(restId, query); } }