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:
@@ -0,0 +1,117 @@
|
||||
package dev.lions.unionflow.server.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.validation.constraints.Max;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* Entité FeedbackEvenement représentant l'évaluation d'un membre sur un événement
|
||||
*
|
||||
* @author UnionFlow Team
|
||||
* @version 1.0
|
||||
* @since 2026-03-16
|
||||
*/
|
||||
@Entity
|
||||
@Table(
|
||||
name = "feedbacks_evenement",
|
||||
indexes = {
|
||||
@Index(name = "idx_feedback_membre", columnList = "membre_id"),
|
||||
@Index(name = "idx_feedback_evenement", columnList = "evenement_id"),
|
||||
@Index(name = "idx_feedback_date", columnList = "date_feedback")
|
||||
},
|
||||
uniqueConstraints = {
|
||||
@UniqueConstraint(
|
||||
name = "uk_feedback_membre_evenement",
|
||||
columnNames = {"membre_id", "evenement_id"})
|
||||
})
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class FeedbackEvenement extends BaseEntity {
|
||||
|
||||
@NotNull
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "membre_id", nullable = false)
|
||||
private Membre membre;
|
||||
|
||||
@NotNull
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "evenement_id", nullable = false)
|
||||
private Evenement evenement;
|
||||
|
||||
@NotNull
|
||||
@Min(1)
|
||||
@Max(5)
|
||||
@Column(name = "note", nullable = false)
|
||||
private Integer note;
|
||||
|
||||
@Column(name = "commentaire", length = 1000)
|
||||
private String commentaire;
|
||||
|
||||
@Builder.Default
|
||||
@Column(name = "date_feedback", nullable = false)
|
||||
private LocalDateTime dateFeedback = LocalDateTime.now();
|
||||
|
||||
@Column(name = "moderation_statut", length = 20)
|
||||
@Builder.Default
|
||||
private String moderationStatut = ModerationStatut.PUBLIE.name();
|
||||
|
||||
@Column(name = "raison_moderation", length = 500)
|
||||
private String raisonModeration;
|
||||
|
||||
/** Énumération des statuts de modération */
|
||||
public enum ModerationStatut {
|
||||
PUBLIE, // Visible publiquement
|
||||
EN_ATTENTE, // En attente de modération
|
||||
REJETE // Rejeté par modération
|
||||
}
|
||||
|
||||
// Méthodes utilitaires
|
||||
|
||||
/** Vérifie si le feedback est publié */
|
||||
public boolean isPublie() {
|
||||
return ModerationStatut.PUBLIE.name().equals(this.moderationStatut);
|
||||
}
|
||||
|
||||
/** Marque le feedback comme en attente de modération */
|
||||
public void mettreEnAttente(String raison) {
|
||||
this.moderationStatut = ModerationStatut.EN_ATTENTE.name();
|
||||
this.raisonModeration = raison;
|
||||
setDateModification(LocalDateTime.now());
|
||||
}
|
||||
|
||||
/** Publie le feedback */
|
||||
public void publier() {
|
||||
this.moderationStatut = ModerationStatut.PUBLIE.name();
|
||||
this.raisonModeration = null;
|
||||
setDateModification(LocalDateTime.now());
|
||||
}
|
||||
|
||||
/** Rejette le feedback */
|
||||
public void rejeter(String raison) {
|
||||
this.moderationStatut = ModerationStatut.REJETE.name();
|
||||
this.raisonModeration = raison;
|
||||
setDateModification(LocalDateTime.now());
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
public void preUpdate() {
|
||||
super.onUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"FeedbackEvenement{id=%s, membre=%s, evenement=%s, note=%d, dateFeedback=%s}",
|
||||
getId(),
|
||||
membre != null ? membre.getEmail() : "null",
|
||||
evenement != null ? evenement.getTitre() : "null",
|
||||
note,
|
||||
dateFeedback);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user