From 6d80795e44ea539f1848457e743479389c5488fc Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Thu, 29 Jan 2026 15:46:00 +0100 Subject: [PATCH] feat: add WebSocket notifications for new comments - Introduced enriched comment retrieval with user information and like statistics. - Implemented WebSocket notifications to notify users of new comments on content. - Updated dependency injection to include `EventsGateway` and `RealtimeModule`. --- backend/src/comments/comments.module.ts | 3 +- backend/src/comments/comments.service.ts | 33 +++++++++++++++++-- .../repositories/comments.repository.ts | 21 ++++++++++++ 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/backend/src/comments/comments.module.ts b/backend/src/comments/comments.module.ts index 2913b98..a8f8e3e 100644 --- a/backend/src/comments/comments.module.ts +++ b/backend/src/comments/comments.module.ts @@ -1,5 +1,6 @@ import { Module } from "@nestjs/common"; import { AuthModule } from "../auth/auth.module"; +import { RealtimeModule } from "../realtime/realtime.module"; import { S3Module } from "../s3/s3.module"; import { CommentsController } from "./comments.controller"; import { CommentsService } from "./comments.service"; @@ -7,7 +8,7 @@ import { CommentLikesRepository } from "./repositories/comment-likes.repository" import { CommentsRepository } from "./repositories/comments.repository"; @Module({ - imports: [AuthModule, S3Module], + imports: [AuthModule, S3Module, RealtimeModule], controllers: [CommentsController], providers: [CommentsService, CommentsRepository, CommentLikesRepository], exports: [CommentsService], diff --git a/backend/src/comments/comments.service.ts b/backend/src/comments/comments.service.ts index e1ce823..5868e34 100644 --- a/backend/src/comments/comments.service.ts +++ b/backend/src/comments/comments.service.ts @@ -3,6 +3,7 @@ import { Injectable, NotFoundException, } from "@nestjs/common"; +import { EventsGateway } from "../realtime/events.gateway"; import { S3Service } from "../s3/s3.service"; import type { CreateCommentDto } from "./dto/create-comment.dto"; import { CommentLikesRepository } from "./repositories/comment-likes.repository"; @@ -14,6 +15,7 @@ export class CommentsService { private readonly commentsRepository: CommentsRepository, private readonly commentLikesRepository: CommentLikesRepository, private readonly s3Service: S3Service, + private readonly eventsGateway: EventsGateway, ) {} async create(userId: string, contentId: string, dto: CreateCommentDto) { @@ -24,11 +26,36 @@ export class CommentsService { parentId: dto.parentId, }); - // Enrichir le commentaire créé (pour le retour API) + // Récupérer le commentaire avec les infos utilisateur pour le WebSocket + const enrichedComment = await this.findOneEnriched(comment.id, userId); + + // Notifier les autres utilisateurs sur ce contenu + this.eventsGateway.sendToContent(contentId, "new_comment", enrichedComment); + + return enrichedComment; + } + + async findOneEnriched(commentId: string, currentUserId?: string) { + const comment = await this.commentsRepository.findOneEnriched(commentId); + if (!comment) return null; + + const [likesCount, isLiked] = await Promise.all([ + this.commentLikesRepository.countByCommentId(comment.id), + currentUserId + ? this.commentLikesRepository.isLikedByUser(comment.id, currentUserId) + : Promise.resolve(false), + ]); + return { ...comment, - likesCount: 0, - isLiked: false, + likesCount, + isLiked, + user: { + ...comment.user, + avatarUrl: comment.user.avatarUrl + ? this.s3Service.getPublicUrl(comment.user.avatarUrl) + : null, + }, }; } diff --git a/backend/src/comments/repositories/comments.repository.ts b/backend/src/comments/repositories/comments.repository.ts index 4459c0f..1c96859 100644 --- a/backend/src/comments/repositories/comments.repository.ts +++ b/backend/src/comments/repositories/comments.repository.ts @@ -45,6 +45,27 @@ export class CommentsRepository { return results[0]; } + async findOneEnriched(id: string) { + const results = await this.databaseService.db + .select({ + id: comments.id, + text: comments.text, + parentId: comments.parentId, + createdAt: comments.createdAt, + updatedAt: comments.updatedAt, + user: { + uuid: users.uuid, + username: users.username, + displayName: users.displayName, + avatarUrl: users.avatarUrl, + }, + }) + .from(comments) + .innerJoin(users, eq(comments.userId, users.uuid)) + .where(and(eq(comments.id, id), isNull(comments.deletedAt))); + return results[0]; + } + async delete(id: string) { await this.databaseService.db .update(comments)