feat: implement per-user soft delete for conversations with automatic restoration on new messages

This commit is contained in:
pradeepkumar
2026-04-10 16:48:12 +05:30
parent d80f75a39e
commit 78133497b3
2 changed files with 39 additions and 7 deletions

View File

@@ -507,6 +507,10 @@ model Conversation {
userClearedAt DateTime? userClearedAt DateTime?
agentClearedAt DateTime? agentClearedAt DateTime?
// Soft delete (per-user) — conversation hidden for that user until a new message arrives
userDeletedAt DateTime?
agentDeletedAt DateTime?
// Timestamps // Timestamps
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt

View File

@@ -140,6 +140,21 @@ export class MessagesService {
}, },
include: conversationInclude, include: conversationInclude,
}); });
} else {
// Clear soft-delete flag for the caller so the conversation reappears
const needsClear = callerRole === UserRole.AGENT
? conversation.agentDeletedAt !== null
: conversation.userDeletedAt !== null;
if (needsClear) {
conversation = await this.prisma.conversation.update({
where: { id: conversation.id },
data: callerRole === UserRole.AGENT
? { agentDeletedAt: null }
: { userDeletedAt: null },
include: conversationInclude,
});
}
} }
// Transform to include otherParty based on caller role // Transform to include otherParty based on caller role
@@ -275,6 +290,9 @@ export class MessagesService {
...(isUser ...(isUser
? { agentUnreadCount: { increment: 1 } } ? { agentUnreadCount: { increment: 1 } }
: { userUnreadCount: { increment: 1 } }), : { userUnreadCount: { increment: 1 } }),
// Clear soft-delete flags so conversation reappears for both parties
userDeletedAt: null,
agentDeletedAt: null,
}, },
}); });
@@ -315,7 +333,10 @@ export class MessagesService {
} }
conversations = await this.prisma.conversation.findMany({ conversations = await this.prisma.conversation.findMany({
where: { agentProfileId: agentProfile.id }, where: {
agentProfileId: agentProfile.id,
agentDeletedAt: null, // Exclude soft-deleted conversations
},
include: { include: {
user: { user: {
select: { select: {
@@ -362,7 +383,10 @@ export class MessagesService {
} else { } else {
// Regular user // Regular user
conversations = await this.prisma.conversation.findMany({ conversations = await this.prisma.conversation.findMany({
where: { userId }, where: {
userId,
userDeletedAt: null, // Exclude soft-deleted conversations
},
include: { include: {
agentProfile: { agentProfile: {
select: { select: {
@@ -781,13 +805,17 @@ export class MessagesService {
throw new ForbiddenException('You are not part of this conversation'); throw new ForbiddenException('You are not part of this conversation');
} }
// Delete all messages first, then the conversation // Soft delete: mark conversation as deleted for this user only
await this.prisma.message.deleteMany({ // The other party still sees the conversation and all messages.
where: { conversationId }, // If a new message arrives later, the deletedAt flag is cleared so
}); // the conversation reappears for the user who deleted it.
const now = new Date();
await this.prisma.conversation.delete({ await this.prisma.conversation.update({
where: { id: conversationId }, where: { id: conversationId },
data: isUser
? { userDeletedAt: now, userClearedAt: now, userUnreadCount: 0 }
: { agentDeletedAt: now, agentClearedAt: now, agentUnreadCount: 0 },
}); });
return null; return null;