diff --git a/src/agents/agents.controller.ts b/src/agents/agents.controller.ts index d837e6e..fb10cf3 100644 --- a/src/agents/agents.controller.ts +++ b/src/agents/agents.controller.ts @@ -227,6 +227,19 @@ export class AgentsController { return this.agentsService.updatePrivacyPreferences(userId, data); } + // Delete account endpoint + + @Delete('account') + @UseGuards(JwtAuthGuard, RolesGuard) + @Roles(UserRole.AGENT) + @ApiBearerAuth() + @ApiOperation({ summary: 'Delete agent account permanently (Agents only)' }) + @ApiResponse({ status: 200, description: 'Account deleted successfully' }) + @ApiResponse({ status: 404, description: 'User not found' }) + async deleteAccount(@CurrentUser('id') userId: string) { + return this.agentsService.deleteAccount(userId); + } + // Public parameterized routes - MUST come after specific routes like profile/* @Get(':id') @Public() diff --git a/src/agents/agents.service.ts b/src/agents/agents.service.ts index bb30fdd..e26604d 100644 --- a/src/agents/agents.service.ts +++ b/src/agents/agents.service.ts @@ -893,4 +893,50 @@ export class AgentsService { return updatedUser.privacyPreferences; } + + // ============================================= + // DELETE ACCOUNT + // ============================================= + + async deleteAccount(userId: string) { + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + select: { id: true, role: true }, + }); + + if (!user) { + throw new NotFoundException('User not found'); + } + + if (user.role !== 'AGENT') { + throw new BadRequestException('This endpoint is for agents only'); + } + + // Delete in a transaction to ensure data consistency + await this.prisma.$transaction(async (tx) => { + // First, delete the agent profile and related data + const agentProfile = await tx.agentProfile.findUnique({ + where: { userId }, + }); + + if (agentProfile) { + // Delete agent profile field values + await tx.agentProfileFieldValue.deleteMany({ + where: { agentProfileId: agentProfile.id }, + }); + + // Delete the agent profile + await tx.agentProfile.delete({ + where: { userId }, + }); + } + + // Finally, delete the user account + await tx.user.delete({ + where: { id: userId }, + }); + }); + + return { message: 'Account deleted successfully' }; + } } diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index d3f46e8..6be1c2e 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -2,6 +2,7 @@ import { Controller, Get, Put, + Delete, Param, Patch, Body, @@ -176,6 +177,19 @@ export class UsersController { return this.usersService.updatePrivacyPreferences(user.id, data); } + // ============================================= + // DELETE ACCOUNT + // ============================================= + + @Delete('account') + @Roles(UserRole.USER) + @ApiOperation({ summary: 'Delete user account permanently (Regular users only)' }) + @ApiResponse({ status: 200, description: 'Account deleted successfully' }) + @ApiResponse({ status: 404, description: 'User not found' }) + async deleteAccount(@CurrentUser() user: { id: string }) { + return this.usersService.deleteAccount(user.id); + } + // ============================================= // ADMIN ENDPOINTS // ============================================= diff --git a/src/users/users.service.ts b/src/users/users.service.ts index f7843be..1538ce5 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -485,4 +485,38 @@ export class UsersService { return updatedUser.privacyPreferences; } + + // ============================================= + // DELETE ACCOUNT + // ============================================= + + async deleteAccount(userId: string) { + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + select: { id: true, role: true }, + }); + + if (!user) { + throw new NotFoundException('User not found'); + } + + if (user.role !== UserRole.USER) { + throw new BadRequestException('This endpoint is for regular users only'); + } + + // Delete in a transaction to ensure data consistency + await this.prisma.$transaction(async (tx) => { + // Delete user profile if it exists + await tx.userProfile.deleteMany({ + where: { userId }, + }); + + // Delete the user account + await tx.user.delete({ + where: { id: userId }, + }); + }); + + return { message: 'Account deleted successfully' }; + } }