From dfd8bc38a551a20369281300822f583dc4cca776 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Mon, 26 Jan 2026 23:12:22 +0530 Subject: [PATCH] feat: Introduce an admin endpoint to update agent types and enhance user profile retrieval to include agent type details. --- src/users/users.controller.ts | 16 +++++ src/users/users.service.ts | 116 +++++++++++++++++++++++++++++----- 2 files changed, 116 insertions(+), 16 deletions(-) diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 512f1b4..a7de9d2 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -116,4 +116,20 @@ export class UsersController { message: 'User status updated successfully', }; } + + @Patch(':id/agent-type') + @Roles(UserRole.ADMIN) + @ApiOperation({ summary: 'Update agent type for an agent user (Admin only)' }) + @ApiResponse({ + status: 200, + description: 'Agent type updated successfully', + }) + @ApiResponse({ status: 400, description: 'Invalid agent type or user is not an agent' }) + @ApiResponse({ status: 404, description: 'User not found' }) + async updateAgentType( + @Param('id') id: string, + @Body('agentTypeId') agentTypeId: string, + ) { + return this.usersService.updateAgentType(id, agentTypeId); + } } diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 55fff6a..635f277 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -1,9 +1,9 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, BadRequestException, NotFoundException } from '@nestjs/common'; import { UserStatus, UserRole, Prisma } from '@prisma/client'; import { PrismaService } from '../prisma/prisma.service'; type UserWithProfiles = Prisma.UserGetPayload<{ - include: { userProfile: true; agentProfile: true }; + include: { userProfile: true; agentProfile: { include: { agentType: true } } }; }>; @Injectable() @@ -24,7 +24,11 @@ export class UsersService { orderBy: { createdAt: 'desc' }, include: { userProfile: true, - agentProfile: true, + agentProfile: { + include: { + agentType: true, + }, + }, }, }) as Promise, this.prisma.user.count({ where }), @@ -69,7 +73,11 @@ export class UsersService { where: { id }, include: { userProfile: true, - agentProfile: true, + agentProfile: { + include: { + agentType: true, + }, + }, }, })) as UserWithProfiles | null; @@ -77,27 +85,60 @@ export class UsersService { return null; } - // Get the appropriate profile based on role - const profile = user.role === UserRole.AGENT ? user.agentProfile : user.userProfile; - - return { + // Base user data + const baseData = { id: user.id, email: user.email, role: user.role, status: user.status, emailVerified: user.emailVerified, + emailVerifiedAt: user.emailVerifiedAt, authProvider: user.authProvider, createdAt: user.createdAt, lastLoginAt: user.lastLoginAt, - profile: profile + }; + + // For agents, return full agent profile + if (user.role === UserRole.AGENT && user.agentProfile) { + return { + ...baseData, + profile: { + firstName: user.agentProfile.firstName, + lastName: user.agentProfile.lastName, + avatar: user.agentProfile.avatar, + phone: user.agentProfile.phone, + city: user.agentProfile.city, + state: user.agentProfile.state, + country: user.agentProfile.country, + }, + agentProfile: { + id: user.agentProfile.id, + slug: user.agentProfile.slug, + bio: user.agentProfile.bio, + headline: user.agentProfile.headline, + companyName: user.agentProfile.companyName, + licenseNumber: user.agentProfile.licenseNumber, + yearsOfExperience: user.agentProfile.yearsOfExperience, + isProfileComplete: user.agentProfile.isProfileComplete, + profileCompleteness: user.agentProfile.profileCompleteness, + agentTypeId: user.agentProfile.agentTypeId, + agentType: user.agentProfile.agentType, + }, + }; + } + + // For regular users + return { + ...baseData, + profile: user.userProfile ? { - firstName: profile.firstName, - lastName: profile.lastName, - avatar: profile.avatar, - phone: profile.phone, - city: profile.city, - state: profile.state, - country: profile.country, + firstName: user.userProfile.firstName, + lastName: user.userProfile.lastName, + avatar: user.userProfile.avatar, + phone: user.userProfile.phone, + city: user.userProfile.city, + state: user.userProfile.state, + country: user.userProfile.country, } : null, }; @@ -109,4 +150,47 @@ export class UsersService { data: { status }, }); } + + async updateAgentType(userId: string, agentTypeId: string) { + // Get user to verify they are an agent + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + include: { agentProfile: true }, + }); + + if (!user) { + throw new NotFoundException('User not found'); + } + + if (user.role !== UserRole.AGENT) { + throw new BadRequestException('User is not an agent'); + } + + if (!user.agentProfile) { + throw new NotFoundException('Agent profile not found'); + } + + // Verify agent type exists + const agentType = await this.prisma.agentType.findUnique({ + where: { id: agentTypeId }, + }); + + if (!agentType) { + throw new BadRequestException('Invalid agent type'); + } + + // Update agent profile with new agent type + const updatedProfile = await this.prisma.agentProfile.update({ + where: { id: user.agentProfile.id }, + data: { agentTypeId }, + include: { agentType: true }, + }); + + return { + id: user.id, + agentTypeId: updatedProfile.agentTypeId, + agentType: updatedProfile.agentType, + message: 'Agent type updated successfully', + }; + } }