import { Controller, Get, Put, Patch, Body } from "@nestjs/common"; import { ApiTags, ApiBearerAuth, ApiOperation, ApiOkResponse, } from "@nestjs/swagger"; import { BaseController } from "../../common/base"; import { UsersService } from "./users.service"; import { CreateUserDto, UpdateUserDto, UpdateProfileDto, ChangePasswordDto, } from "./dto/user.dto"; import { CurrentUser, Roles } from "../../common/decorators"; import { ApiResponse, createSuccessResponse, } from "../../common/types/api-response.type"; import { User } from "@prisma/client"; import { plainToInstance } from "class-transformer"; import { UserResponseDto } from "./dto/user.dto"; interface AuthenticatedUser { id: string; email: string; role: string; } @ApiTags("Users") @ApiBearerAuth() @Controller("users") export class UsersController extends BaseController< User, CreateUserDto, UpdateUserDto > { constructor(private readonly usersService: UsersService) { super(usersService, "User"); } @Get("me") @ApiOperation({ summary: "Get current authenticated user profile" }) @ApiOkResponse({ type: UserResponseDto }) async getMe( @CurrentUser() user: AuthenticatedUser, ): Promise> { const fullUser = await this.usersService.findOneWithDetails(user.id); return createSuccessResponse( plainToInstance(UserResponseDto, fullUser), "User profile retrieved successfully", ); } @Put("me") @ApiOperation({ summary: "Update current user profile" }) @ApiOkResponse({ type: UserResponseDto }) async updateMe( @CurrentUser() user: AuthenticatedUser, @Body() dto: UpdateProfileDto, ): Promise> { const updatedUser = await this.usersService.updateProfile(user.id, dto); return createSuccessResponse( plainToInstance(UserResponseDto, updatedUser), "User profile updated successfully", ); } @Patch("me/password") @ApiOperation({ summary: "Change current user password" }) @ApiOkResponse({ description: "Password changed successfully" }) async changePassword( @CurrentUser() user: AuthenticatedUser, @Body() dto: ChangePasswordDto, ): Promise> { await this.usersService.changePassword( user.id, dto.currentPassword, dto.newPassword, ); return createSuccessResponse(null, "Password changed successfully"); } // Override create to require admin role @Roles("admin") async create( ...args: Parameters< BaseController["create"] > ) { return super.create(...args); } // Override delete to require admin role @Roles("admin") async delete( ...args: Parameters< BaseController["delete"] > ) { return super.delete(...args); } }