import { Controller, Get, Put, Delete, Body, Param, UseGuards, Req, HttpStatus, Logger, } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiParam, } from '@nestjs/swagger'; import { UsersService } from './users.service'; import { JwtAuthGuard } from '../auth/auth.guard'; import { UpdateUserDto, UserResponseDto, UserStatsDto } from './users.entity'; export interface AuthenticatedRequest { user: { id: string; email: string; plan: string; quotaRemaining: number; isActive: boolean; }; } @ApiTags('Users') @Controller('users') @UseGuards(JwtAuthGuard) @ApiBearerAuth() export class UsersController { private readonly logger = new Logger(UsersController.name); constructor(private readonly usersService: UsersService) {} @Get('me') @ApiOperation({ summary: 'Get current user profile', description: 'Returns the authenticated user\'s profile information' }) @ApiResponse({ status: 200, description: 'User profile retrieved successfully', type: UserResponseDto }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 404, description: 'User not found' }) async getProfile(@Req() req: AuthenticatedRequest): Promise { return await this.usersService.getProfile(req.user.id); } @Put('me') @ApiOperation({ summary: 'Update current user profile', description: 'Updates the authenticated user\'s profile information' }) @ApiResponse({ status: 200, description: 'User profile updated successfully', type: UserResponseDto }) @ApiResponse({ status: 400, description: 'Invalid update data' }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 404, description: 'User not found' }) async updateProfile( @Req() req: AuthenticatedRequest, @Body() updateData: UpdateUserDto, ): Promise { this.logger.log(`User ${req.user.email} updating profile`); return await this.usersService.updateProfile(req.user.id, updateData); } @Get('me/stats') @ApiOperation({ summary: 'Get current user statistics', description: 'Returns usage statistics for the authenticated user' }) @ApiResponse({ status: 200, description: 'User statistics retrieved successfully', type: UserStatsDto }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 404, description: 'User not found' }) async getUserStats(@Req() req: AuthenticatedRequest): Promise { return await this.usersService.getUserStats(req.user.id); } @Delete('me') @ApiOperation({ summary: 'Deactivate current user account', description: 'Deactivates the authenticated user\'s account (soft delete)' }) @ApiResponse({ status: 200, description: 'User account deactivated successfully', type: UserResponseDto }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 404, description: 'User not found' }) async deactivateAccount(@Req() req: AuthenticatedRequest): Promise { this.logger.log(`User ${req.user.email} deactivating account`); return await this.usersService.deactivateAccount(req.user.id); } @Put('me/reactivate') @ApiOperation({ summary: 'Reactivate current user account', description: 'Reactivates the authenticated user\'s account' }) @ApiResponse({ status: 200, description: 'User account reactivated successfully', type: UserResponseDto }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 404, description: 'User not found' }) async reactivateAccount(@Req() req: AuthenticatedRequest): Promise { this.logger.log(`User ${req.user.email} reactivating account`); return await this.usersService.reactivateAccount(req.user.id); } @Get(':id') @ApiOperation({ summary: 'Get user by ID', description: 'Returns user information by ID (admin/internal use)' }) @ApiParam({ name: 'id', description: 'User unique identifier', example: '550e8400-e29b-41d4-a716-446655440000' }) @ApiResponse({ status: 200, description: 'User retrieved successfully', type: UserResponseDto }) @ApiResponse({ status: 401, description: 'Unauthorized' }) @ApiResponse({ status: 404, description: 'User not found' }) async findOne(@Param('id') id: string): Promise { return await this.usersService.findOne(id); } @Get('me/quota/check') @ApiOperation({ summary: 'Check user quota availability', description: 'Checks if the user has sufficient quota for operations' }) @ApiResponse({ status: 200, description: 'Quota check completed', schema: { type: 'object', properties: { hasQuota: { type: 'boolean', example: true }, quotaRemaining: { type: 'number', example: 45 }, quotaUsed: { type: 'number', example: 5 }, totalQuota: { type: 'number', example: 50 }, plan: { type: 'string', example: 'BASIC' }, } } }) @ApiResponse({ status: 401, description: 'Unauthorized' }) async checkQuota(@Req() req: AuthenticatedRequest) { const hasQuota = await this.usersService.hasQuota(req.user.id); const stats = await this.usersService.getUserStats(req.user.id); return { hasQuota, quotaRemaining: req.user.quotaRemaining, quotaUsed: stats.quotaUsed, totalQuota: stats.totalQuota, plan: req.user.plan, }; } }