feat(backend): Ajout complet des fonctionnalités Chat, Social, Story et Notifications
Implémentation complète de toutes les fonctionnalités backend : ## Nouvelles Fonctionnalités ### Chat (Messagerie Instantanée) - Entities : Conversation, Message - DTOs : ConversationResponseDTO, MessageResponseDTO, SendMessageRequestDTO - Resources : MessageResource (endpoints REST) - Services : MessageService (logique métier) - Repositories : ConversationRepository, MessageRepository - WebSocket : ChatWebSocket (temps réel) ### Social (Publications Sociales) - Entities : SocialPost, SocialComment, SocialLike - DTOs : SocialPostResponseDTO, CreateSocialPostRequestDTO - Resources : SocialPostResource - Services : SocialPostService - Repositories : SocialPostRepository ### Story (Stories temporaires) - Entities : Story, StoryView - DTOs : StoryResponseDTO, CreateStoryRequestDTO - Resources : StoryResource - Services : StoryService - Repositories : StoryRepository ### Notifications (Temps Réel) - Entities : Notification - DTOs : NotificationResponseDTO - Resources : NotificationResource - Services : NotificationService, PresenceService - Repositories : NotificationRepository - WebSocket : NotificationWebSocket (temps réel) ## Améliorations ### Users & Friendship - Mise à jour UserResponseDTO avec nouveaux champs - Amélioration FriendshipResource avec séparation demandes envoyées/reçues - FriendSuggestionResponseDTO pour suggestions d'amis - Optimisations dans UsersService et FriendshipService ### Events - Améliorations EventsResource et EventService - Optimisations EventsRepository ### Configuration - Mise à jour application.properties - Configuration docker-compose.yml - Dockerfile pour développement ## Fichiers Modifiés - .dockerignore, .gitignore - README.md - docker-compose.yml - Configuration Maven wrapper
This commit is contained in:
333
src/main/java/com/lions/dev/resource/MessageResource.java
Normal file
333
src/main/java/com/lions/dev/resource/MessageResource.java
Normal file
@@ -0,0 +1,333 @@
|
||||
package com.lions.dev.resource;
|
||||
|
||||
import com.lions.dev.dto.request.chat.SendMessageRequestDTO;
|
||||
import com.lions.dev.dto.response.chat.ConversationResponseDTO;
|
||||
import com.lions.dev.dto.response.chat.MessageResponseDTO;
|
||||
import com.lions.dev.entity.chat.Conversation;
|
||||
import com.lions.dev.entity.chat.Message;
|
||||
import com.lions.dev.entity.users.Users;
|
||||
import com.lions.dev.repository.UsersRepository;
|
||||
import com.lions.dev.service.MessageService;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Resource REST pour la gestion des messages et conversations.
|
||||
*
|
||||
* Cette classe expose les endpoints HTTP pour:
|
||||
* - Envoyer des messages
|
||||
* - Récupérer les conversations
|
||||
* - Récupérer les messages d'une conversation
|
||||
* - Marquer les messages comme lus
|
||||
* - Supprimer des messages et conversations
|
||||
*/
|
||||
@Path("/messages")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Messages", description = "Gestion des messages et conversations")
|
||||
public class MessageResource {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(MessageResource.class);
|
||||
|
||||
@Inject
|
||||
MessageService messageService;
|
||||
|
||||
@Inject
|
||||
UsersRepository usersRepository;
|
||||
|
||||
/**
|
||||
* Envoie un nouveau message.
|
||||
*
|
||||
* @param request Le DTO contenant les informations du message
|
||||
* @return Le message créé
|
||||
*/
|
||||
@POST
|
||||
@Operation(summary = "Envoyer un message", description = "Envoie un nouveau message à un utilisateur")
|
||||
public Response sendMessage(SendMessageRequestDTO request) {
|
||||
LOG.info("[LOG] Réception d'une demande d'envoi de message");
|
||||
|
||||
try {
|
||||
// Validation
|
||||
if (!request.isValid()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity("{\"message\": \"Données invalides\"}")
|
||||
.build();
|
||||
}
|
||||
|
||||
// Envoyer le message
|
||||
Message message = messageService.sendMessage(
|
||||
request.getSenderId(),
|
||||
request.getRecipientId(),
|
||||
request.getContent(),
|
||||
request.getMessageType(),
|
||||
request.getMediaUrl()
|
||||
);
|
||||
|
||||
MessageResponseDTO response = new MessageResponseDTO(message);
|
||||
return Response.status(Response.Status.CREATED).entity(response).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors de l'envoi du message : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors de l'envoi du message\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère toutes les conversations d'un utilisateur.
|
||||
*
|
||||
* @param userId L'ID de l'utilisateur
|
||||
* @return Liste des conversations
|
||||
*/
|
||||
@GET
|
||||
@Path("/conversations/{userId}")
|
||||
@Operation(summary = "Récupérer les conversations", description = "Récupère toutes les conversations d'un utilisateur")
|
||||
public Response getUserConversations(@PathParam("userId") UUID userId) {
|
||||
LOG.info("[LOG] Récupération des conversations pour l'utilisateur ID : " + userId);
|
||||
|
||||
try {
|
||||
Users user = usersRepository.findById(userId);
|
||||
if (user == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity("{\"message\": \"Utilisateur non trouvé\"}")
|
||||
.build();
|
||||
}
|
||||
|
||||
List<Conversation> conversations = messageService.getUserConversations(userId);
|
||||
List<ConversationResponseDTO> response = conversations.stream()
|
||||
.map(conv -> new ConversationResponseDTO(conv, user))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Response.ok(response).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors de la récupération des conversations : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors de la récupération des conversations\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les messages d'une conversation.
|
||||
*
|
||||
* @param conversationId L'ID de la conversation
|
||||
* @param page Le numéro de la page (défaut: 0)
|
||||
* @param size La taille de la page (défaut: 50)
|
||||
* @return Liste des messages
|
||||
*/
|
||||
@GET
|
||||
@Path("/conversation/{conversationId}")
|
||||
@Operation(summary = "Récupérer les messages", description = "Récupère les messages d'une conversation avec pagination")
|
||||
public Response getConversationMessages(
|
||||
@PathParam("conversationId") UUID conversationId,
|
||||
@QueryParam("page") @DefaultValue("0") int page,
|
||||
@QueryParam("size") @DefaultValue("50") int size) {
|
||||
LOG.info("[LOG] Récupération des messages pour la conversation ID : " + conversationId);
|
||||
|
||||
try {
|
||||
List<Message> messages = messageService.getConversationMessages(conversationId, page, size);
|
||||
List<MessageResponseDTO> response = messages.stream()
|
||||
.map(MessageResponseDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Response.ok(response).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors de la récupération des messages : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors de la récupération des messages\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère une conversation entre deux utilisateurs.
|
||||
*
|
||||
* @param user1Id L'ID du premier utilisateur
|
||||
* @param user2Id L'ID du deuxième utilisateur
|
||||
* @return La conversation
|
||||
*/
|
||||
@GET
|
||||
@Path("/conversation/between/{user1Id}/{user2Id}")
|
||||
@Operation(summary = "Récupérer une conversation", description = "Récupère la conversation entre deux utilisateurs")
|
||||
public Response getConversationBetweenUsers(
|
||||
@PathParam("user1Id") UUID user1Id,
|
||||
@PathParam("user2Id") UUID user2Id) {
|
||||
LOG.info("[LOG] Recherche de conversation entre " + user1Id + " et " + user2Id);
|
||||
|
||||
try {
|
||||
Users user1 = usersRepository.findById(user1Id);
|
||||
if (user1 == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity("{\"message\": \"Utilisateur non trouvé\"}")
|
||||
.build();
|
||||
}
|
||||
|
||||
Conversation conversation = messageService.getConversationBetweenUsers(user1Id, user2Id);
|
||||
|
||||
if (conversation == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity("{\"message\": \"Conversation non trouvée\"}")
|
||||
.build();
|
||||
}
|
||||
|
||||
ConversationResponseDTO response = new ConversationResponseDTO(conversation, user1);
|
||||
return Response.ok(response).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors de la récupération de la conversation : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors de la récupération de la conversation\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marque un message comme lu.
|
||||
*
|
||||
* @param messageId L'ID du message
|
||||
* @return Le message mis à jour
|
||||
*/
|
||||
@PUT
|
||||
@Path("/{messageId}/read")
|
||||
@Operation(summary = "Marquer comme lu", description = "Marque un message comme lu")
|
||||
public Response markMessageAsRead(@PathParam("messageId") UUID messageId) {
|
||||
LOG.info("[LOG] Marquage du message comme lu : " + messageId);
|
||||
|
||||
try {
|
||||
Message message = messageService.markMessageAsRead(messageId);
|
||||
MessageResponseDTO response = new MessageResponseDTO(message);
|
||||
return Response.ok(response).build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors du marquage du message : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors du marquage du message\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marque tous les messages d'une conversation comme lus.
|
||||
*
|
||||
* @param conversationId L'ID de la conversation
|
||||
* @param userId L'ID de l'utilisateur
|
||||
* @return Le nombre de messages marqués comme lus
|
||||
*/
|
||||
@PUT
|
||||
@Path("/conversation/{conversationId}/read/{userId}")
|
||||
@Operation(summary = "Marquer tout comme lu", description = "Marque tous les messages d'une conversation comme lus")
|
||||
public Response markAllMessagesAsRead(
|
||||
@PathParam("conversationId") UUID conversationId,
|
||||
@PathParam("userId") UUID userId) {
|
||||
LOG.info("[LOG] Marquage de tous les messages comme lus pour la conversation " + conversationId);
|
||||
|
||||
try {
|
||||
int count = messageService.markAllMessagesAsRead(conversationId, userId);
|
||||
return Response.ok("{\"messagesMarkedAsRead\": " + count + "}").build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors du marquage des messages : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors du marquage des messages\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le nombre total de messages non lus pour un utilisateur.
|
||||
*
|
||||
* @param userId L'ID de l'utilisateur
|
||||
* @return Le nombre de messages non lus
|
||||
*/
|
||||
@GET
|
||||
@Path("/unread/count/{userId}")
|
||||
@Operation(summary = "Compter les non lus", description = "Compte le nombre total de messages non lus")
|
||||
public Response getTotalUnreadCount(@PathParam("userId") UUID userId) {
|
||||
LOG.info("[LOG] Récupération du nombre de messages non lus pour l'utilisateur " + userId);
|
||||
|
||||
try {
|
||||
long count = messageService.getTotalUnreadCount(userId);
|
||||
return Response.ok("{\"unreadCount\": " + count + "}").build();
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors du comptage des messages non lus : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors du comptage\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime un message.
|
||||
*
|
||||
* @param messageId L'ID du message
|
||||
* @return Confirmation de suppression
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/{messageId}")
|
||||
@Operation(summary = "Supprimer un message", description = "Supprime un message")
|
||||
public Response deleteMessage(@PathParam("messageId") UUID messageId) {
|
||||
LOG.info("[LOG] Suppression du message ID : " + messageId);
|
||||
|
||||
try {
|
||||
boolean deleted = messageService.deleteMessage(messageId);
|
||||
|
||||
if (deleted) {
|
||||
return Response.ok("{\"message\": \"Message supprimé avec succès\"}").build();
|
||||
} else {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity("{\"message\": \"Message non trouvé\"}")
|
||||
.build();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors de la suppression du message : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors de la suppression\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Supprime une conversation.
|
||||
*
|
||||
* @param conversationId L'ID de la conversation
|
||||
* @return Confirmation de suppression
|
||||
*/
|
||||
@DELETE
|
||||
@Path("/conversation/{conversationId}")
|
||||
@Operation(summary = "Supprimer une conversation", description = "Supprime une conversation et tous ses messages")
|
||||
public Response deleteConversation(@PathParam("conversationId") UUID conversationId) {
|
||||
LOG.info("[LOG] Suppression de la conversation ID : " + conversationId);
|
||||
|
||||
try {
|
||||
boolean deleted = messageService.deleteConversation(conversationId);
|
||||
|
||||
if (deleted) {
|
||||
return Response.ok("{\"message\": \"Conversation supprimée avec succès\"}").build();
|
||||
} else {
|
||||
return Response.status(Response.Status.NOT_FOUND)
|
||||
.entity("{\"message\": \"Conversation non trouvée\"}")
|
||||
.build();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("[ERROR] Erreur lors de la suppression de la conversation : " + e.getMessage(), e);
|
||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
||||
.entity("{\"message\": \"Erreur lors de la suppression\"}")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user