feat(backend): endpoints inscriptions + feedback événements
Ajoute infrastructure complète pour gérer inscriptions et feedbacks événements.
## Entités
- FeedbackEvenement : note 1-5, commentaire, modération (PUBLIE/EN_ATTENTE/REJETE)
- InscriptionEvenement : déjà existait, utilisation ajoutée
## Repositories
- InscriptionEvenementRepository : findByMembreAndEvenement, findByEvenement, countConfirmees, isMembreInscrit
- FeedbackEvenementRepository : findByMembreAndEvenement, findPubliesByEvenement, calculateAverageNote
## Service (EvenementService)
Inscriptions :
- inscrireEvenement() : vérifie capacité, crée inscription CONFIRMEE
- desinscrireEvenement() : soft delete inscription
- getParticipants() : liste inscriptions confirmées
- getMesInscriptions() : inscriptions du membre connecté
Feedbacks :
- soumetteFeedback() : note 1-5 + commentaire, vérifie participation, événement terminé
- getFeedbacks() : liste feedbacks publiés
- getStatistiquesFeedback() : note moyenne + nombre feedbacks
## REST Endpoints (6 total)
Inscriptions :
- POST /api/evenements/{id}/inscriptions - S'inscrire
- DELETE /api/evenements/{id}/inscriptions - Se désinscrire
- GET /api/evenements/{id}/participants - Liste participants
- GET /api/evenements/mes-inscriptions - Mes inscriptions
Feedbacks :
- POST /api/evenements/{id}/feedback - Soumettre feedback (note+commentaire)
- GET /api/evenements/{id}/feedbacks - Liste feedbacks + stats
## Database
- Migration V7 : table feedbacks_evenement
- Contrainte unique: un feedback par membre/événement
- Index: membre_id, evenement_id, date_feedback, moderation_statut
Débloquer fonctionnalités événements mobile.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,11 +3,14 @@ package dev.lions.unionflow.server.resource;
|
||||
import dev.lions.unionflow.server.api.dto.common.PagedResponse;
|
||||
import dev.lions.unionflow.server.dto.EvenementMobileDTO;
|
||||
import dev.lions.unionflow.server.entity.Evenement;
|
||||
import dev.lions.unionflow.server.entity.FeedbackEvenement;
|
||||
import dev.lions.unionflow.server.entity.InscriptionEvenement;
|
||||
import dev.lions.unionflow.server.service.EvenementService;
|
||||
import io.quarkus.panache.common.Page;
|
||||
import io.quarkus.panache.common.Sort;
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.ws.rs.*;
|
||||
@@ -286,4 +289,112 @@ public class EvenementResource {
|
||||
boolean inscrit = evenementService.isUserInscrit(id);
|
||||
return Response.ok(Map.of("inscrit", inscrit)).build();
|
||||
}
|
||||
|
||||
// === GESTION DES INSCRIPTIONS ===
|
||||
|
||||
/** S'inscrire à un événement */
|
||||
@POST
|
||||
@Path("/{id}/inscriptions")
|
||||
@Operation(summary = "S'inscrire à un événement")
|
||||
@APIResponse(responseCode = "201", description = "Inscription créée")
|
||||
@APIResponse(responseCode = "400", description = "Déjà inscrit ou événement complet")
|
||||
@APIResponse(responseCode = "404", description = "Événement non trouvé")
|
||||
@RolesAllowed({ "ADMIN", "PRESIDENT", "SECRETAIRE", "ORGANISATEUR_EVENEMENT", "MEMBRE", "USER" })
|
||||
@Transactional
|
||||
public Response inscrireEvenement(@PathParam("id") UUID evenementId) {
|
||||
try {
|
||||
InscriptionEvenement inscription = evenementService.inscrireEvenement(evenementId);
|
||||
return Response.status(Response.Status.CREATED).entity(inscription).build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Se désinscrire d'un événement */
|
||||
@DELETE
|
||||
@Path("/{id}/inscriptions")
|
||||
@Operation(summary = "Se désinscrire d'un événement")
|
||||
@APIResponse(responseCode = "204", description = "Désinscription effectuée")
|
||||
@APIResponse(responseCode = "404", description = "Inscription non trouvée")
|
||||
@RolesAllowed({ "ADMIN", "PRESIDENT", "SECRETAIRE", "ORGANISATEUR_EVENEMENT", "MEMBRE", "USER" })
|
||||
@Transactional
|
||||
public Response desinscrireEvenement(@PathParam("id") UUID evenementId) {
|
||||
evenementService.desinscrireEvenement(evenementId);
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
/** Liste des participants d'un événement */
|
||||
@GET
|
||||
@Path("/{id}/participants")
|
||||
@Operation(summary = "Liste des participants")
|
||||
@APIResponse(responseCode = "200", description = "Liste des participants")
|
||||
@RolesAllowed({ "ADMIN", "PRESIDENT", "SECRETAIRE", "ORGANISATEUR_EVENEMENT", "MEMBRE" })
|
||||
public Response getParticipants(@PathParam("id") UUID evenementId) {
|
||||
List<InscriptionEvenement> participants = evenementService.getParticipants(evenementId);
|
||||
return Response.ok(participants).build();
|
||||
}
|
||||
|
||||
/** Mes inscriptions */
|
||||
@GET
|
||||
@Path("/mes-inscriptions")
|
||||
@Operation(summary = "Mes inscriptions aux événements")
|
||||
@APIResponse(responseCode = "200", description = "Liste de mes inscriptions")
|
||||
@RolesAllowed({ "ADMIN", "PRESIDENT", "SECRETAIRE", "ORGANISATEUR_EVENEMENT", "MEMBRE", "USER" })
|
||||
public Response getMesInscriptions() {
|
||||
List<InscriptionEvenement> inscriptions = evenementService.getMesInscriptions();
|
||||
return Response.ok(inscriptions).build();
|
||||
}
|
||||
|
||||
// === GESTION DES FEEDBACKS ===
|
||||
|
||||
/** Soumettre un feedback */
|
||||
@POST
|
||||
@Path("/{id}/feedback")
|
||||
@Operation(summary = "Soumettre un feedback sur l'événement")
|
||||
@APIResponse(responseCode = "201", description = "Feedback créé")
|
||||
@APIResponse(responseCode = "400", description = "Données invalides ou feedback déjà soumis")
|
||||
@APIResponse(responseCode = "404", description = "Événement non trouvé")
|
||||
@RolesAllowed({ "ADMIN", "PRESIDENT", "SECRETAIRE", "ORGANISATEUR_EVENEMENT", "MEMBRE", "USER" })
|
||||
@Transactional
|
||||
public Response soumetteFeedback(
|
||||
@PathParam("id") UUID evenementId, Map<String, Object> requestBody) {
|
||||
|
||||
Integer note = (Integer) requestBody.get("note");
|
||||
String commentaire = (String) requestBody.get("commentaire");
|
||||
|
||||
if (note == null || note < 1 || note > 5) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "La note doit être entre 1 et 5"))
|
||||
.build();
|
||||
}
|
||||
|
||||
try {
|
||||
FeedbackEvenement feedback =
|
||||
evenementService.soumetteFeedback(evenementId, note, commentaire);
|
||||
return Response.status(Response.Status.CREATED).entity(feedback).build();
|
||||
} catch (IllegalStateException e) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", e.getMessage()))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
/** Liste des feedbacks d'un événement */
|
||||
@GET
|
||||
@Path("/{id}/feedbacks")
|
||||
@Operation(summary = "Liste des feedbacks de l'événement")
|
||||
@APIResponse(responseCode = "200", description = "Liste des feedbacks")
|
||||
public Response getFeedbacks(@PathParam("id") UUID evenementId) {
|
||||
List<FeedbackEvenement> feedbacks = evenementService.getFeedbacks(evenementId);
|
||||
Map<String, Object> stats = evenementService.getStatistiquesFeedback(evenementId);
|
||||
|
||||
return Response.ok(
|
||||
Map.of(
|
||||
"feedbacks", feedbacks,
|
||||
"noteMoyenne", stats.get("noteMoyenne"),
|
||||
"nombreFeedbacks", stats.get("nombreFeedbacks")))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user