From b8d133783be858ef95ad6c0e67738c5d9cab250c Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Sat, 28 Mar 2026 20:25:15 +0530 Subject: [PATCH] feat: implement per-user chat clearing by filtering messages based on new clearedAt timestamps --- prisma/schema.prisma | 4 ++++ src/messages/messages.service.ts | 35 +++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index dc54919..182da03 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -503,6 +503,10 @@ model Conversation { userFavorited Boolean @default(false) agentFavorited Boolean @default(false) + // Clear chat (per-user) — messages before this timestamp are hidden for that user + userClearedAt DateTime? + agentClearedAt DateTime? + // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/src/messages/messages.service.ts b/src/messages/messages.service.ts index 3516bd8..1f3492b 100644 --- a/src/messages/messages.service.ts +++ b/src/messages/messages.service.ts @@ -343,8 +343,12 @@ export class MessagesService { // Map to include unread count from agent perspective return conversations.map((conv) => { const showStatus = this.shouldShowOnlineStatus(conv.user.privacyPreferences); + const cleared = conv.agentClearedAt; + const isCleared = cleared && conv.lastMessageAt && new Date(cleared) >= new Date(conv.lastMessageAt); return { ...conv, + lastMessageText: isCleared ? null : conv.lastMessageText, + lastMessageAt: isCleared ? null : conv.lastMessageAt, unreadCount: conv.agentUnreadCount, otherParty: { id: conv.user.id, @@ -388,8 +392,12 @@ export class MessagesService { // Map to include unread count from user perspective return conversations.map((conv) => { const showStatus = this.shouldShowOnlineStatus(conv.agentProfile.user.privacyPreferences); + const cleared = conv.userClearedAt; + const isCleared = cleared && conv.lastMessageAt && new Date(cleared) >= new Date(conv.lastMessageAt); return { ...conv, + lastMessageText: isCleared ? null : conv.lastMessageText, + lastMessageAt: isCleared ? null : conv.lastMessageAt, unreadCount: conv.userUnreadCount, otherParty: { id: conv.agentProfile.id, @@ -437,9 +445,16 @@ export class MessagesService { const skip = (page - 1) * limit; + // Filter out messages cleared by this user + const clearedAt = isUser ? conversation.userClearedAt : conversation.agentClearedAt; + const messageWhere: any = { conversationId }; + if (clearedAt) { + messageWhere.createdAt = { gt: clearedAt }; + } + const [messages, total] = await Promise.all([ this.prisma.message.findMany({ - where: { conversationId }, + where: messageWhere, include: { sender: { select: { @@ -466,7 +481,7 @@ export class MessagesService { skip, take: limit, }), - this.prisma.message.count({ where: { conversationId } }), + this.prisma.message.count({ where: messageWhere }), ]); return { @@ -704,7 +719,8 @@ export class MessagesService { } /** - * Clear all messages in a conversation (keep the conversation itself) + * Clear chat for the requesting user only (messages are hidden, not deleted) + * The other party still sees all messages. */ async clearChat(conversationId: string, userId: string) { const conversation = await this.prisma.conversation.findUnique({ @@ -727,19 +743,14 @@ export class MessagesService { throw new ForbiddenException('You are not part of this conversation'); } - // Delete all messages - await this.prisma.message.deleteMany({ - where: { conversationId }, - }); + const now = new Date(); - // Reset conversation preview + // Set clearedAt timestamp for the requesting user only await this.prisma.conversation.update({ where: { id: conversationId }, data: { - lastMessageAt: null, - lastMessageText: null, - userUnreadCount: 0, - agentUnreadCount: 0, + ...(isUser ? { userClearedAt: now, userUnreadCount: 0 } : {}), + ...(isAgent ? { agentClearedAt: now, agentUnreadCount: 0 } : {}), }, });