feat: Introduce agent profile verification history tracking and status notifications for agents.

This commit is contained in:
pradeepkumar
2026-03-21 08:55:57 +05:30
parent 31439c3b06
commit 3e7e3683ed
4 changed files with 120 additions and 1 deletions

View File

@@ -473,4 +473,55 @@ export class NotificationsService implements OnModuleInit {
},
);
}
@OnEvent('notification.verification')
async handleVerificationNotification(event: {
recipientUserId: string;
status: string;
note?: string;
agentName: string;
}) {
const isApproved = event.status === 'APPROVED';
const actionUrl = '/agent/dashboard';
const title = isApproved
? 'Profile Verified!'
: 'Profile Verification Update';
const description = isApproved
? 'Congratulations! Your profile has been verified. You now have the verified badge on your profile.'
: `Your profile verification was not approved.${event.note ? ` Reason: ${event.note}` : ''} Please review and resubmit.`;
// Create in-app notification + push (always for verification)
const user = await this.prisma.user.findUnique({
where: { id: event.recipientUserId },
select: { email: true, fcmTokens: true },
});
if (!user) return;
// Always create in-app notification
await this.prisma.notification.create({
data: {
userId: event.recipientUserId,
type: 'system',
title,
description,
actionUrl,
data: { type: 'verification', status: event.status, link: actionUrl },
},
});
// Always send push notification
await this.sendPushNotification(event.recipientUserId, user, {
title,
body: description,
data: { type: 'verification', status: event.status, link: actionUrl },
});
// Always send email — forced, ignores preferences
if (user.email) {
await this.sendEmailNotification(user.email, title, description, actionUrl);
}
}
}

View File

@@ -330,6 +330,16 @@ export class UsersController {
return this.usersService.updateVerification(id, data, admin.id);
}
@Get(':id/verification-history')
@Roles(UserRole.ADMIN)
@ApiOperation({ summary: 'Admin: Get verification history for an agent' })
async getVerificationHistory(@Param('id') id: string) {
const user = await this.usersService.findOne(id);
const agentProfileId = (user as any)?.agentProfile?.id;
if (!agentProfileId) throw new NotFoundException('Agent profile not found');
return this.usersService.getVerificationHistory(agentProfileId);
}
// ==========================================
// ADMIN MANAGEMENT (SUPER_ADMIN only)
// ==========================================

View File

@@ -1,6 +1,7 @@
import { Injectable, BadRequestException, NotFoundException, ForbiddenException } from '@nestjs/common';
import { UserStatus, UserRole, Prisma, VerificationStatus } from '@prisma/client';
import { PrismaService } from '../prisma/prisma.service';
import { EventEmitter2 } from '@nestjs/event-emitter';
import * as argon2 from 'argon2';
type UserWithProfiles = Prisma.UserGetPayload<{
@@ -9,7 +10,10 @@ type UserWithProfiles = Prisma.UserGetPayload<{
@Injectable()
export class UsersService {
constructor(private readonly prisma: PrismaService) {}
constructor(
private readonly prisma: PrismaService,
private readonly eventEmitter: EventEmitter2,
) {}
// =============================================
// USER PROFILE METHODS (for regular users)
@@ -390,6 +394,24 @@ export class UsersService {
},
});
// Save verification history
await this.prisma.verificationHistory.create({
data: {
agentProfileId: user.agentProfile.id,
status: data.status,
note: data.note || null,
adminId,
},
});
// Emit notification to the agent
this.eventEmitter.emit('notification.verification', {
recipientUserId: userId,
status: data.status,
note: data.note,
agentName: `${updatedProfile.firstName || ''} ${updatedProfile.lastName || ''}`.trim(),
});
return {
id: user.id,
agentProfileId: updatedProfile.id,
@@ -402,6 +424,17 @@ export class UsersService {
};
}
// Get verification history for an agent
async getVerificationHistory(agentProfileId: string) {
return this.prisma.verificationHistory.findMany({
where: { agentProfileId },
include: {
admin: { select: { id: true, email: true } },
},
orderBy: { createdAt: 'desc' },
});
}
// =============================================
// NOTIFICATION PREFERENCES
// =============================================