diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java index 3dc1f3c..6ae2572 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java @@ -1,139 +1,203 @@ package dev.lions.unionflow.server.resource; import dev.lions.unionflow.server.api.dto.notification.NotificationDTO; -import dev.lions.unionflow.server.api.enums.notification.TypeNotification; +import dev.lions.unionflow.server.api.dto.notification.TemplateNotificationDTO; import dev.lions.unionflow.server.service.NotificationService; -import jakarta.enterprise.context.ApplicationScoped; +import jakarta.annotation.security.PermitAll; import jakarta.inject.Inject; +import jakarta.validation.Valid; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.tags.Tag; +import java.util.UUID; import org.jboss.logging.Logger; -/** Resource REST pour la gestion des notifications */ +/** + * Resource REST pour la gestion des notifications + * + * @author UnionFlow Team + * @version 3.0 + * @since 2025-01-29 + */ @Path("/api/notifications") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -@ApplicationScoped -@Tag(name = "Notifications", description = "API de gestion des notifications") +@PermitAll public class NotificationResource { private static final Logger LOG = Logger.getLogger(NotificationResource.class); @Inject NotificationService notificationService; + // ======================================== + // TEMPLATES + // ======================================== + + /** + * Crée un nouveau template de notification + * + * @param templateDTO DTO du template à créer + * @return Template créé + */ @POST - @Operation(summary = "Envoyer une notification") - @APIResponse(responseCode = "200", description = "Notification envoyée") - public Response envoyerNotification(NotificationDTO notification) { - LOG.infof("Envoi de notification: %s", notification.getTitre()); + @Path("/templates") + public Response creerTemplate(@Valid TemplateNotificationDTO templateDTO) { try { - CompletableFuture future = notificationService.envoyerNotification(notification); - NotificationDTO result = future.get(); - return Response.ok(result).build(); + TemplateNotificationDTO result = notificationService.creerTemplate(templateDTO); + return Response.status(Response.Status.CREATED).entity(result).build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse(e.getMessage())) + .build(); } catch (Exception e) { - LOG.errorf(e, "Erreur lors de l'envoi de notification"); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(Map.of("message", e.getMessage())) + LOG.errorf(e, "Erreur lors de la création du template"); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse("Erreur lors de la création du template: " + e.getMessage())) .build(); } } + // ======================================== + // NOTIFICATIONS + // ======================================== + + /** + * Crée une nouvelle notification + * + * @param notificationDTO DTO de la notification à créer + * @return Notification créée + */ @POST - @Path("/groupe") - @Operation(summary = "Envoyer une notification à un groupe") - @APIResponse(responseCode = "200", description = "Notifications envoyées") - public Response envoyerNotificationGroupe( - @QueryParam("type") TypeNotification type, - @QueryParam("titre") String titre, - @QueryParam("message") String message, - List destinatairesIds) { - LOG.infof("Envoi de notification de groupe: %d destinataires", destinatairesIds.size()); + public Response creerNotification(@Valid NotificationDTO notificationDTO) { try { - CompletableFuture> future = - notificationService.envoyerNotificationGroupe(type, titre, message, destinatairesIds, Map.of()); - List results = future.get(); - return Response.ok(results).build(); + NotificationDTO result = notificationService.creerNotification(notificationDTO); + return Response.status(Response.Status.CREATED).entity(result).build(); } catch (Exception e) { - LOG.errorf(e, "Erreur lors de l'envoi de notifications groupées"); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(Map.of("message", e.getMessage())) + LOG.errorf(e, "Erreur lors de la création de la notification"); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse("Erreur lors de la création de la notification: " + e.getMessage())) .build(); } } - @GET - @Path("/utilisateur/{utilisateurId}") - @Operation(summary = "Obtenir les notifications d'un utilisateur") - @APIResponse(responseCode = "200", description = "Notifications récupérées") - public Response obtenirNotifications( - @PathParam("utilisateurId") String utilisateurId, - @QueryParam("includeArchivees") @DefaultValue("false") boolean includeArchivees, - @QueryParam("limite") @DefaultValue("50") int limite) { - LOG.infof("Récupération notifications pour: %s", utilisateurId); - List notifications = - notificationService.obtenirNotificationsUtilisateur(utilisateurId, includeArchivees, limite); - return Response.ok(notifications).build(); - } - - @PUT - @Path("/{notificationId}/lue") - @Operation(summary = "Marquer une notification comme lue") - @APIResponse(responseCode = "200", description = "Notification marquée comme lue") - public Response marquerCommeLue( - @PathParam("notificationId") String notificationId, - @QueryParam("utilisateurId") String utilisateurId) { - LOG.infof("Marquage comme lue: %s", notificationId); - boolean succes = notificationService.marquerCommeLue(notificationId, utilisateurId); - return Response.ok(Map.of("success", succes)).build(); - } - - @PUT - @Path("/{notificationId}/archiver") - @Operation(summary = "Archiver une notification") - @APIResponse(responseCode = "200", description = "Notification archivée") - public Response archiverNotification( - @PathParam("notificationId") String notificationId, - @QueryParam("utilisateurId") String utilisateurId) { - LOG.infof("Archivage: %s", notificationId); - boolean succes = notificationService.archiverNotification(notificationId, utilisateurId); - return Response.ok(Map.of("success", succes)).build(); - } - - @GET - @Path("/stats") - @Operation(summary = "Obtenir les statistiques des notifications") - @APIResponse(responseCode = "200", description = "Statistiques récupérées") - public Response obtenirStatistiques() { - Map stats = notificationService.obtenirStatistiques(); - return Response.ok(stats).build(); - } - + /** + * Marque une notification comme lue + * + * @param id ID de la notification + * @return Notification mise à jour + */ @POST - @Path("/test/{utilisateurId}") - @Operation(summary = "Envoyer une notification de test") - @APIResponse(responseCode = "200", description = "Notification de test envoyée") - public Response envoyerNotificationTest( - @PathParam("utilisateurId") String utilisateurId, - @QueryParam("type") @DefaultValue("SYSTEME") TypeNotification type) { - LOG.infof("Envoi notification de test: %s", utilisateurId); + @Path("/{id}/marquer-lue") + public Response marquerCommeLue(@PathParam("id") UUID id) { try { - CompletableFuture future = - notificationService.envoyerNotificationTest(utilisateurId, type); - NotificationDTO result = future.get(); + NotificationDTO result = notificationService.marquerCommeLue(id); + return Response.ok(result).build(); + } catch (jakarta.ws.rs.NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ErrorResponse("Notification non trouvée")) + .build(); + } catch (Exception e) { + LOG.errorf(e, "Erreur lors du marquage de la notification"); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse("Erreur lors du marquage de la notification: " + e.getMessage())) + .build(); + } + } + + /** + * Trouve une notification par son ID + * + * @param id ID de la notification + * @return Notification + */ + @GET + @Path("/{id}") + public Response trouverNotificationParId(@PathParam("id") UUID id) { + try { + NotificationDTO result = notificationService.trouverNotificationParId(id); + return Response.ok(result).build(); + } catch (jakarta.ws.rs.NotFoundException e) { + return Response.status(Response.Status.NOT_FOUND) + .entity(new ErrorResponse("Notification non trouvée")) + .build(); + } catch (Exception e) { + LOG.errorf(e, "Erreur lors de la recherche de la notification"); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse("Erreur lors de la recherche de la notification: " + e.getMessage())) + .build(); + } + } + + /** + * Liste toutes les notifications d'un membre + * + * @param membreId ID du membre + * @return Liste des notifications + */ + @GET + @Path("/membre/{membreId}") + public Response listerNotificationsParMembre(@PathParam("membreId") UUID membreId) { + try { + List result = notificationService.listerNotificationsParMembre(membreId); return Response.ok(result).build(); } catch (Exception e) { - LOG.errorf(e, "Erreur lors de l'envoi de notification de test"); - return Response.status(Response.Status.INTERNAL_SERVER_ERROR) - .entity(Map.of("message", e.getMessage())) + LOG.errorf(e, "Erreur lors de la liste des notifications"); + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse("Erreur lors de la liste des notifications: " + e.getMessage())) .build(); } } + + /** + * Liste les notifications non lues d'un membre + * + * @param membreId ID du membre + * @return Liste des notifications non lues + */ + @GET + @Path("/membre/{membreId}/non-lues") + public Response listerNotificationsNonLuesParMembre(@PathParam("membreId") UUID membreId) { + try { + List result = notificationService.listerNotificationsNonLuesParMembre(membreId); + return Response.ok(result).build(); + } catch (Exception e) { + LOG.errorf(e, "Erreur lors de la liste des notifications non lues"); + return Response.status(Response.Status.BAD_REQUEST) + .entity( + new ErrorResponse( + "Erreur lors de la liste des notifications non lues: " + e.getMessage())) + .build(); + } + } + + /** + * Liste les notifications en attente d'envoi + * + * @return Liste des notifications en attente + */ + @GET + @Path("/en-attente-envoi") + public Response listerNotificationsEnAttenteEnvoi() { + try { + List result = notificationService.listerNotificationsEnAttenteEnvoi(); + return Response.ok(result).build(); + } catch (Exception e) { + LOG.errorf(e, "Erreur lors de la liste des notifications en attente"); + return Response.status(Response.Status.BAD_REQUEST) + .entity( + new ErrorResponse( + "Erreur lors de la liste des notifications en attente: " + e.getMessage())) + .build(); + } + } + + /** Classe interne pour les réponses d'erreur */ + public static class ErrorResponse { + public String error; + + public ErrorResponse(String error) { + this.error = error; + } + } } -