- Migration de Jakarta WebSocket vers Quarkus WebSockets Next - Implémentation de l'architecture Kafka pour événements temps réel - Ajout des DTOs d'événements (NotificationEvent, ChatMessageEvent, ReactionEvent, PresenceEvent) - Création des bridges Kafka → WebSocket (NotificationKafkaBridge, ChatKafkaBridge, ReactionKafkaBridge) - Mise à jour des services pour publier dans Kafka au lieu d'appeler directement WebSocket - Suppression des classes obsolètes (ChatWebSocket, NotificationWebSocket) - Correction de l'injection des paramètres path dans WebSockets Next (utilisation de connection.pathParam) - Ajout des migrations DB pour bookings, promotions, business hours, amenities, reviews - Mise à jour de la configuration application.properties pour Kafka et WebSockets Next - Mise à jour .gitignore pour ignorer les fichiers de logs
234 lines
11 KiB
Java
234 lines
11 KiB
Java
package com.lions.dev.resource;
|
|
|
|
import com.lions.dev.dto.request.establishment.EstablishmentRatingRequestDTO;
|
|
import com.lions.dev.dto.response.establishment.EstablishmentRatingResponseDTO;
|
|
import com.lions.dev.dto.response.establishment.EstablishmentRatingStatsResponseDTO;
|
|
import com.lions.dev.entity.establishment.EstablishmentRating;
|
|
import com.lions.dev.service.EstablishmentRatingService;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.transaction.Transactional;
|
|
import jakarta.validation.Valid;
|
|
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.Map;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* Ressource REST pour la gestion des notations d'établissements.
|
|
* Cette classe expose des endpoints pour soumettre, modifier et récupérer les notes.
|
|
*/
|
|
@Path("/establishments/{establishmentId}/ratings")
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
@Consumes(MediaType.APPLICATION_JSON)
|
|
@Tag(name = "Establishment Ratings", description = "Opérations liées aux notations des établissements")
|
|
public class EstablishmentRatingResource {
|
|
|
|
@Inject
|
|
EstablishmentRatingService ratingService;
|
|
|
|
private static final Logger LOG = Logger.getLogger(EstablishmentRatingResource.class);
|
|
|
|
/**
|
|
* Soumet une nouvelle note pour un établissement.
|
|
*/
|
|
@POST
|
|
@Transactional
|
|
@Operation(summary = "Soumettre une note pour un établissement",
|
|
description = "Soumet une nouvelle note (1 à 5 étoiles) pour un établissement")
|
|
public Response submitRating(
|
|
@PathParam("establishmentId") String establishmentId,
|
|
@QueryParam("userId") String userIdStr,
|
|
@Valid EstablishmentRatingRequestDTO requestDTO) {
|
|
LOG.info("Soumission d'une note pour l'établissement " + establishmentId + " par l'utilisateur " + userIdStr);
|
|
|
|
try {
|
|
UUID id = UUID.fromString(establishmentId);
|
|
UUID userId = UUID.fromString(userIdStr);
|
|
|
|
EstablishmentRating rating = ratingService.submitRating(id, userId, requestDTO);
|
|
EstablishmentRatingResponseDTO responseDTO = new EstablishmentRatingResponseDTO(rating);
|
|
return Response.status(Response.Status.CREATED).entity(responseDTO).build();
|
|
} catch (IllegalArgumentException e) {
|
|
LOG.error("ID invalide : " + e.getMessage());
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity("ID invalide : " + e.getMessage())
|
|
.build();
|
|
} catch (RuntimeException e) {
|
|
LOG.error("Erreur lors de la soumission de la note : " + e.getMessage());
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity(e.getMessage())
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur inattendue lors de la soumission de la note", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity("Erreur lors de la soumission de la note")
|
|
.build();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Met à jour une note existante.
|
|
*/
|
|
@PUT
|
|
@Transactional
|
|
@Operation(summary = "Modifier une note existante",
|
|
description = "Met à jour une note existante pour un établissement")
|
|
public Response updateRating(
|
|
@PathParam("establishmentId") String establishmentId,
|
|
@QueryParam("userId") String userIdStr,
|
|
@Valid EstablishmentRatingRequestDTO requestDTO) {
|
|
LOG.info("Mise à jour de la note pour l'établissement " + establishmentId + " par l'utilisateur " + userIdStr);
|
|
|
|
try {
|
|
UUID id = UUID.fromString(establishmentId);
|
|
UUID userId = UUID.fromString(userIdStr);
|
|
|
|
EstablishmentRating rating = ratingService.updateRating(id, userId, requestDTO);
|
|
EstablishmentRatingResponseDTO responseDTO = new EstablishmentRatingResponseDTO(rating);
|
|
return Response.ok(responseDTO).build();
|
|
} catch (IllegalArgumentException e) {
|
|
LOG.error("ID invalide : " + e.getMessage());
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity("ID invalide : " + e.getMessage())
|
|
.build();
|
|
} catch (RuntimeException e) {
|
|
LOG.error("Erreur lors de la mise à jour de la note : " + e.getMessage());
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity(e.getMessage())
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur inattendue lors de la mise à jour de la note", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity("Erreur lors de la mise à jour de la note")
|
|
.build();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Récupère les statistiques de notation d'un établissement.
|
|
* Doit être déclaré avant les endpoints génériques GET pour la résolution correcte par JAX-RS.
|
|
*/
|
|
@GET
|
|
@Path("/stats")
|
|
@Operation(summary = "Récupérer les statistiques de notation",
|
|
description = "Récupère les statistiques de notation d'un établissement (moyenne, total, distribution)")
|
|
public Response getRatingStats(@PathParam("establishmentId") String establishmentId) {
|
|
LOG.info("Récupération des statistiques de notation pour l'établissement " + establishmentId);
|
|
|
|
try {
|
|
UUID id = UUID.fromString(establishmentId);
|
|
Map<String, Object> stats = ratingService.getRatingStats(id);
|
|
|
|
EstablishmentRatingStatsResponseDTO responseDTO = new EstablishmentRatingStatsResponseDTO(
|
|
(Double) stats.get("averageRating"),
|
|
(Integer) stats.get("totalRatingsCount"),
|
|
(Map<Integer, Integer>) stats.get("ratingDistribution")
|
|
);
|
|
return Response.ok(responseDTO).build();
|
|
} catch (IllegalArgumentException e) {
|
|
LOG.error("ID invalide : " + e.getMessage());
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity("ID invalide : " + e.getMessage())
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur inattendue lors de la récupération des statistiques", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity("Erreur lors de la récupération des statistiques")
|
|
.build();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Récupère la note d'un utilisateur pour un établissement (via path parameter).
|
|
* Endpoint alternatif pour compatibilité.
|
|
*/
|
|
@GET
|
|
@Path("/users/{userId}")
|
|
@Operation(summary = "Récupérer la note d'un utilisateur (path parameter)",
|
|
description = "Récupère la note donnée par un utilisateur spécifique pour un établissement (via path parameter)")
|
|
public Response getUserRatingByPath(
|
|
@PathParam("establishmentId") String establishmentId,
|
|
@PathParam("userId") String userIdStr) {
|
|
LOG.info("Récupération de la note de l'utilisateur " + userIdStr + " pour l'établissement " + establishmentId);
|
|
|
|
try {
|
|
UUID id = UUID.fromString(establishmentId);
|
|
UUID userId = UUID.fromString(userIdStr);
|
|
|
|
EstablishmentRating rating = ratingService.getUserRating(id, userId);
|
|
if (rating == null) {
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity("Note non trouvée")
|
|
.build();
|
|
}
|
|
|
|
EstablishmentRatingResponseDTO responseDTO = new EstablishmentRatingResponseDTO(rating);
|
|
return Response.ok(responseDTO).build();
|
|
} catch (IllegalArgumentException e) {
|
|
LOG.error("ID invalide : " + e.getMessage(), e);
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity("ID invalide : " + e.getMessage())
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur inattendue lors de la récupération de la note", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity("Erreur lors de la récupération de la note")
|
|
.build();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Récupère la note d'un utilisateur pour un établissement (via query parameter).
|
|
* Endpoint utilisé par le frontend Flutter.
|
|
* Doit être déclaré en dernier car c'est l'endpoint le plus générique.
|
|
*/
|
|
@GET
|
|
@Operation(summary = "Récupérer la note d'un utilisateur",
|
|
description = "Récupère la note donnée par un utilisateur spécifique pour un établissement (via query parameter userId)")
|
|
public Response getUserRatingByQuery(
|
|
@PathParam("establishmentId") String establishmentId,
|
|
@QueryParam("userId") String userIdStr) {
|
|
LOG.info("Récupération de la note de l'utilisateur " + userIdStr + " pour l'établissement " + establishmentId);
|
|
|
|
// Si userId n'est pas fourni, retourner une erreur
|
|
if (userIdStr == null || userIdStr.isEmpty()) {
|
|
LOG.warn("userId manquant dans la requête");
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity("Le paramètre userId est requis")
|
|
.build();
|
|
}
|
|
|
|
try {
|
|
UUID id = UUID.fromString(establishmentId);
|
|
UUID userId = UUID.fromString(userIdStr);
|
|
|
|
EstablishmentRating rating = ratingService.getUserRating(id, userId);
|
|
if (rating == null) {
|
|
// Retourner 404 si la note n'existe pas
|
|
return Response.status(Response.Status.NOT_FOUND)
|
|
.entity("Note non trouvée")
|
|
.build();
|
|
}
|
|
|
|
EstablishmentRatingResponseDTO responseDTO = new EstablishmentRatingResponseDTO(rating);
|
|
return Response.ok(responseDTO).build();
|
|
} catch (IllegalArgumentException e) {
|
|
LOG.error("ID invalide : " + e.getMessage(), e);
|
|
return Response.status(Response.Status.BAD_REQUEST)
|
|
.entity("ID invalide : " + e.getMessage())
|
|
.build();
|
|
} catch (Exception e) {
|
|
LOG.error("Erreur inattendue lors de la récupération de la note", e);
|
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
|
|
.entity("Erreur lors de la récupération de la note")
|
|
.build();
|
|
}
|
|
}
|
|
}
|
|
|