Refactoring + Checkpoint

This commit is contained in:
DahoudG
2024-11-17 22:58:38 +00:00
parent 588984aa9c
commit 2f33b09753
10 changed files with 278 additions and 50 deletions

View File

@@ -0,0 +1,58 @@
version: '3.8'
services:
# Service pour la base de données PostgreSQL
db:
image: postgres:13
container_name: afterwork_db
environment:
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- "5432:5432"
networks:
- afterwork-network
volumes:
- db_data:/var/lib/postgresql/data
# Service pour l'application Quarkus
app:
build:
context: .
dockerfile: src/main/docker/Dockerfile.jvm
container_name: afterwork-quarkus
environment:
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: db
DB_PORT: 5432
DB_NAME: ${DB_NAME}
JAVA_OPTS_APPEND: "-Dquarkus.http.host=0.0.0.0"
ports:
- "8080:8080"
depends_on:
- db
networks:
- afterwork-network
# Service pour Swagger UI
swagger-ui:
image: swaggerapi/swagger-ui
container_name: afterwork-swagger-ui
environment:
SWAGGER_JSON: http://app:8080/openapi
ports:
- "8081:8080"
depends_on:
- app
networks:
- afterwork-network
networks:
afterwork-network:
driver: bridge
volumes:
db_data:
driver: local

View File

@@ -21,7 +21,9 @@ public class EventCreateResponseDTO {
private String link; // Lien vers plus d'informations
private String imageUrl; // URL d'une image pour l'événement
private String creatorEmail; // Email du créateur de l'événement
private String status;
private String creatorFirstName; // Prénom du créateur de l'événement
private String creatorLastName; // Nom de famille du création de l'événement
private String status; // Statut de l'événement
/**
* Constructeur qui transforme une entité Events en DTO.
@@ -39,6 +41,8 @@ public class EventCreateResponseDTO {
this.link = event.getLink();
this.imageUrl = event.getImageUrl();
this.creatorEmail = event.getCreator().getEmail();
this.creatorFirstName = event.getCreator().getPrenoms();
this.creatorLastName = event.getCreator().getNom();
this.status = event.getStatus();
}
}

View File

@@ -21,6 +21,10 @@ public class EventReadManyByIdResponseDTO {
private String link; // Lien vers plus d'informations
private String imageUrl; // URL de l'image de l'événement
private String status; // Statut de l'événement
private String creatorEmail; // Email de l'utilisateur qui a créé l'événement
private String creatorFirstName; // Prénom de l'utilisateur qui a criané l'événement
private String creatorLastName; // Nom de l'utilisateur qui a criané l'événement
private String profileImageUrl; // URL de l'image de profil de l'utilisateur qui a criané l'événement
/**
* Constructeur qui transforme une entité Events en DTO de réponse.
@@ -38,5 +42,9 @@ public class EventReadManyByIdResponseDTO {
this.link = event.getLink();
this.imageUrl = event.getImageUrl();
this.status = event.getStatus();
this.creatorEmail = event.getCreator().getEmail();
this.creatorFirstName = event.getCreator().getPrenoms();
this.creatorLastName = event.getCreator().getNom();
this.profileImageUrl = event.getCreator().getProfileImageUrl();
}
}

View File

@@ -22,6 +22,7 @@ public class FriendshipReadFriendDetailsResponseDTO {
private String friendLastName; // Nom de l'ami
private String friendFirstName; // Prénom de l'ami
private String friendEmail; // Email de l'ami
private String friendProfileImageUrl;
private FriendshipStatus status; // Statut de la relation d'amitié
private LocalDateTime createdAt; // Date de création de la relation d'amitié
private LocalDateTime updatedAt; // Date de la dernière mise à jour de la relation
@@ -34,19 +35,21 @@ public class FriendshipReadFriendDetailsResponseDTO {
* @param friendLastName Le nom de l'ami.
* @param friendFirstName Le prénom de l'ami.
* @param friendEmail L'email de l'ami.
* @param friendProfileImageUrl L'URL de l'image de profil de l'ami.
* @param status Le statut de la relation d'amitié.
* @param createdAt La date de création de la relation.
* @param updatedAt La date de la dernière mise à jour de la relation.
*/
public FriendshipReadFriendDetailsResponseDTO(UUID userId, UUID friendId, String friendLastName,
String friendFirstName,
String friendEmail, FriendshipStatus status,
String friendEmail, String friendProfileImageUrl, FriendshipStatus status,
LocalDateTime createdAt, LocalDateTime updatedAt) {
this.userId = userId;
this.friendId = friendId;
this.friendLastName = friendLastName;
this.friendFirstName = friendFirstName;
this.friendEmail = friendEmail;
this.friendProfileImageUrl = friendProfileImageUrl;
this.status = status;
this.createdAt = createdAt;
this.updatedAt = updatedAt;

View File

@@ -31,7 +31,7 @@ public class Events extends BaseEntity {
@Column(name = "title", nullable = false)
private String title; // Le titre de l'événement
@Column(name = "description")
@Column(name = "description",length = 1000)
private String description; // La description de l'événement
@Column(name = "start_date", nullable = false)
@@ -55,9 +55,6 @@ public class Events extends BaseEntity {
@Column(name = "status", nullable = false)
private String status = "ouvert"; // Le statut de l'événement (en cours, terminé, annulé, etc.)
@Column(name = "profile_image_url")
private String profileImageUrl; // URL de la photo de profil
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "creator_id", nullable = false)
private Users creator; // L'utilisateur créateur de l'événement

View File

@@ -5,30 +5,53 @@ import com.lions.dev.entity.friends.FriendshipStatus;
import com.lions.dev.entity.users.Users;
import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase;
import jakarta.enterprise.context.ApplicationScoped;
import org.jboss.logging.Logger;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* Repository pour gérer les relations d'amitié (Friendship) dans la base de données.
* Il contient des méthodes pour récupérer, ajouter, et supprimer des relations d'amitié.
* Cette classe contient des méthodes pour récupérer, ajouter, et supprimer des relations d'amitié.
* Elle est utilisée pour interagir avec la table des relations d'amitié en base de données.
*
* Elle est annotée avec @ApplicationScoped pour être gérée par le conteneur CDI de Quarkus.
*/
@ApplicationScoped
public class FriendshipRepository implements PanacheRepositoryBase<Friendship, UUID> {
// Logger pour les logs de la classe
private static final Logger logger = Logger.getLogger(FriendshipRepository.class);
/**
* Trouver une relation d'amitié entre deux utilisateurs.
* Trouver une relation d'amitié entre deux utilisateurs spécifiés.
* Cette méthode recherche une relation d'amitié entre deux utilisateurs donnés.
* Elle peut être utilisée pour vérifier si une demande d'amitié existe déjà.
*
* @param user L'utilisateur qui envoie la demande d'amitié.
* @param friend L'ami qui reçoit la demande.
* @return Une Optional contenant la relation d'amitié si elle existe.
*/
public Optional<Friendship> findByUsers(Users user, Users friend) {
return find("user = ?1 and friend = ?2", user, friend).firstResultOptional();
logger.infof("Recherche de la relation d'amitié entre les utilisateurs : %s et %s", user.getId(), friend.getId());
// Requête qui cherche une relation d'amitié entre deux utilisateurs spécifiques
Optional<Friendship> friendship = find("user = ?1 and friend = ?2", user, friend).firstResultOptional();
if (friendship.isPresent()) {
logger.infof("Relation d'amitié trouvée entre %s et %s", user.getId(), friend.getId());
} else {
logger.warnf("Aucune relation d'amitié trouvée entre %s et %s", user.getId(), friend.getId());
}
return friendship;
}
/**
* Récupérer la liste des amis d'un utilisateur, c'est-à-dire toutes les relations acceptées.
* Récupérer la liste des amis d'un utilisateur avec un statut d'amitié spécifique (ACCEPTED).
* Cette méthode récupère les relations d'amitié acceptées pour un utilisateur donné,
* avec la possibilité de paginer les résultats.
*
* @param user L'utilisateur dont on souhaite récupérer les amis.
* @param page Le numéro de la page à récupérer.
@@ -36,29 +59,40 @@ public class FriendshipRepository implements PanacheRepositoryBase<Friendship, U
* @return Une liste paginée de relations d'amitié acceptées.
*/
public List<Friendship> findFriendsByUser(Users user, int page, int size) {
System.out.println("**************************************************************" + user.getId());
// Utiliser une requête basée sur les IDs pour éviter les duplications
return find("(user.id = ?1 OR friend.id = ?1) AND status = ?2", user.getId(),
FriendshipStatus.ACCEPTED)
logger.infof("Récupération des amis pour l'utilisateur %s, page %d, taille %d", user.getId(), page, size);
// Utilisation d'une requête pour récupérer les relations d'amitié acceptées pour l'utilisateur spécifié
List<Friendship> friendships = find("(user.id = ?1 OR friend.id = ?1) AND status = ?2", user.getId(), FriendshipStatus.ACCEPTED)
.page(page, size)
.stream()
// .filter(friendship -> !friendship.getUser().equals(friendship.getFriend())) // Exclure les relations dupliquées
// .distinct() // Appliquer distinct sur le flux pour éviter tout doublon supplémentaire
.filter(friendship -> !friendship.getUser().equals(friendship.getFriend())) // Exclure les relations où l'utilisateur est ami avec lui-même
.distinct() // Appliquer distinct pour éviter les doublons
.toList();
logger.infof("Nombre d'amis récupérés pour l'utilisateur %s : %d", user.getId(), friendships.size());
return friendships;
}
/**
* Récupérer toutes les relations d'amitié d'un utilisateur avec un statut spécifique.
* Cette méthode permet de filtrer les relations par statut (par exemple, ACCEPTED, PENDING).
* Elle est également paginée.
*
* @param user L'utilisateur dont on souhaite récupérer les amitiés.
* @param status Le statut des relations d'amitié à filtrer.
* @param page Le numéro de la page.
* @param size La taille de la page.
* @param user L'utilisateur dont on souhaite récupérer les relations d'amitié.
* @param status Le statut des relations d'amitié à filtrer (ACCEPTED, PENDING, etc.).
* @param page Le numéro de la page à récupérer.
* @param size La taille de la page (nombre d'éléments).
* @return Une liste paginée de relations d'amitié avec le statut spécifié.
*/
public List<Friendship> findByUserAndStatus(Users user, FriendshipStatus status, int page, int size) {
return find("(user = ?1 or friend = ?1) and status = ?2", user, status)
logger.infof("Récupération des relations d'amitié pour l'utilisateur %s avec le statut %s, page %d, taille %d", user.getId(), status, page, size);
// Requête pour récupérer les relations avec un statut spécifique
List<Friendship> friendships = find("(user = ?1 OR friend = ?1) AND status = ?2", user, status)
.page(page, size)
.list();
logger.infof("Nombre de relations récupérées pour l'utilisateur %s avec le statut %s : %d", user.getId(), status, friendships.size());
return friendships;
}
}

View File

@@ -651,7 +651,6 @@ public class EventsResource {
return Response.ok(responseDTOs).build();
}
@POST
@Path("/{id}/favorite")
@Transactional
@@ -750,5 +749,90 @@ public class EventsResource {
String shareLink = "https://lions.dev /events/" + eventId;
return Response.ok(Map.of("shareLink", shareLink)).build();
}
/**
* Endpoint pour fermer un événement.
*
* @param eventId L'ID de l'événement.
* @return Une réponse HTTP indiquant le succès de la fermeture.
*/
@PATCH
@Path("/{id}/close")
@Transactional
@Operation(
summary = "Fermer un événement",
description = "Ferme un événement et empêche les nouvelles participations"
)
public Response closeEvent(@PathParam("id") UUID eventId) {
LOG.info("Tentative de fermeture de l'événement avec l'ID : " + eventId);
// Recherche de l'événement par ID
Events event = eventsRepository.findById(eventId);
if (event == null) {
LOG.warn("Événement non trouvé avec l'ID : " + eventId);
return Response.status(Response.Status.NOT_FOUND)
.entity("Événement non trouvé.")
.build();
}
// Marquer l'événement comme fermé
event.setStatus("fermé"); // Modification du statut de l'événement
eventsRepository.persist(event); // Persister les modifications dans la base
LOG.info("Événement fermé avec succès : " + event.getTitle());
// Retourner une réponse HTTP 200 OK avec le DTO de l'événement fermé
return Response.ok(new EventCreateResponseDTO(event)).build();
}
/**
* Endpoint pour réouvrir un événement.
*
* @param eventId L'ID de l'événement à rouvrir.
* @return Une réponse HTTP indiquant le succès ou l'échec de la réouverture.
*/
@PATCH
@Path("{eventId}/reopen")
@Transactional
@Operation(
summary = "Rouvrir un événement",
description = "Rouvre un événement existant qui est actuellement fermé"
)
public Response reopenEvent(@PathParam("eventId") UUID eventId) {
LOG.info("Tentative de réouverture de l'événement avec l'ID : " + eventId);
// Recherche de l'événement par ID
Events event = eventsRepository.findById(eventId);
if (event == null) {
LOG.warn("Événement non trouvé avec l'ID : " + eventId);
return Response.status(Response.Status.NOT_FOUND)
.entity("Événement non trouvé.")
.build();
}
// Vérifier si l'événement est déjà ouvert
if ("ouvert".equals(event.getStatus())) {
LOG.warn("L'événement est déjà ouvert : " + eventId);
return Response.status(Response.Status.BAD_REQUEST)
.entity("L'événement est déjà ouvert.")
.build();
}
// Vérifier si l'événement est fermé avant de tenter la réouverture
if (!"fermé".equals(event.getStatus())) {
LOG.warn("L'événement n'est pas fermé, donc il ne peut pas être rouvert : " + eventId);
return Response.status(Response.Status.BAD_REQUEST)
.entity("L'événement n'est pas fermé et ne peut pas être rouvert.")
.build();
}
// Réouvrir l'événement en mettant à jour son statut
event.setStatus("ouvert"); // Changer le statut à "Ouvert"
eventsRepository.persist(event); // Persister les modifications dans la base
LOG.info("Événement rouvert avec succès : " + event.getTitle());
// Retourner une réponse HTTP 200 OK avec un message de succès
return Response.ok("L'événement a été réouvert avec succès.").build();
}
}

View File

@@ -79,14 +79,24 @@ public class FriendshipService {
*/
@Transactional
public FriendshipCreateOneResponseDTO acceptFriendRequest(UUID friendshipId) {
// Vérification de l'ID de la demande d'amitié
if (friendshipId == null) {
logger.error(String.format("[ERROR] L'ID de la demande d'amitié est nul."));
throw new IllegalArgumentException("L'ID de la demande d'amitié est nul.");
}
// Rechercher l'amitié dans la base de données
Friendship friendship = friendshipRepository.findById(friendshipId);
// Si l'amitié n'est pas trouvée, lever une exception
if (friendship == null) {
logger.error(String.format("[ERROR] Demande d'amitié introuvable pour l'ID: %s", friendshipId)); // Correctement formaté
throw new FriendshipNotFoundException("Demande d'amitié introuvable.");
}
// Vérifier que la demande n'est pas déjà acceptée
if (friendship.getStatus() == FriendshipStatus.ACCEPTED) {
logger.error("[ERROR] Demande d'amitié déjà acceptée.");
logger.error(String.format("[ERROR] Demande d'amitié déjà acceptée pour l'ID: %s", friendshipId)); // Correctement formaté
throw new IllegalArgumentException("Demande d'amitié déjà acceptée.");
}
@@ -94,7 +104,10 @@ public class FriendshipService {
friendship.setStatus(FriendshipStatus.ACCEPTED);
friendshipRepository.persist(friendship);
logger.info("[LOG] Demande d'amitié acceptée avec succès.");
// Log de succès
logger.info(String.format("[LOG] Demande d'amitié acceptée avec succès pour l'ID: %s", friendshipId)); // Correctement formaté
// Retourner la réponse avec les informations de la relation d'amitié
return new FriendshipCreateOneResponseDTO(friendship);
}
@@ -175,6 +188,7 @@ public class FriendshipService {
friend.getNom(), // Nom de l'ami
friend.getPrenoms(),
friend.getEmail(), // Email de l'ami
friend.getProfileImageUrl(), // URL de l'image de profil de l'ami
friendship.getStatus(), // Statut de la relation
friendship.getCreatedAt(), // Date de création de la relation
friendship.getUpdatedAt() // Date de mise à jour de la relation
@@ -211,6 +225,7 @@ public class FriendshipService {
friend.getNom(),
friend.getPrenoms(),
friend.getEmail(),
friend.getProfileImageUrl(),
friendship.getStatus(),
friendship.getCreatedAt(),
friendship.getUpdatedAt()

View File

@@ -1,25 +1,35 @@
# Configuration Quarkus
quarkus.http.port=8085
# Configuration Swagger UI
quarkus.swagger-ui.always-include=true
quarkus.swagger-ui.path=/q/swagger-ui
quarkus.smallrye-openapi.path=/openapi
# Configuration de la base de donn<6E>es
quarkus.datasource.db-kind=oracle
quarkus.datasource.jdbc.url=jdbc:oracle:thin:@localhost:1522:ORCLCDB
quarkus.datasource.username=C##AFTERWORK
quarkus.datasource.password=afterwork
quarkus.datasource.jdbc.driver=oracle.jdbc.OracleDriver
quarkus.hibernate-orm.database.generation=update
quarkus.hibernate-orm.log.sql=true
quarkus.datasource.devservices.enabled=false
# Configuration de la base de donn<6E>es PostgreSQL pour Quarkus en d<>veloppement
%dev.quarkus.datasource.db-kind=postgresql
%dev.quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/afterwork_db
%dev.quarkus.datasource.username=${DB_USERNAME}
%dev.quarkus.datasource.password=${DB_PASSWORD}
%dev.quarkus.datasource.jdbc.driver=org.postgresql.Driver
%dev.quarkus.hibernate-orm.database.generation=update
%dev.quarkus.hibernate-orm.log.sql=true
%dev.quarkus.datasource.devservices.enabled=false
# Niveau de logging
quarkus.log.level=INFO
# Configuration de la base de donn<6E>es PostgreSQL pour Quarkus en production
%prod.quarkus.datasource.db-kind=postgresql
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${DB_HOST:localhost}:${DB_PORT:5432}/${DB_NAME:afterwork_db}
%prod.quarkus.datasource.username=${DB_USERNAME}
%prod.quarkus.datasource.password=${DB_PASSWORD}
%prod.quarkus.datasource.jdbc.driver=org.postgresql.Driver
%prod.quarkus.hibernate-orm.database.generation=update
%prod.quarkus.hibernate-orm.log.sql=false
%prod.quarkus.datasource.devservices.enabled=false
# Configuration la cl<63> de signature JWT
# Niveau de logging pour Quarkus en d<>veloppement
%dev.quarkus.log.level=DEBUG
# Niveau de logging pour Quarkus en production
%prod.quarkus.log.level=INFO
# Configuration de la signature JWT
# mp.jwt.verify.publickey.location=META-INF/resources/publicKey.pem
# mp.jwt.verify.issuer=https://issuer.example.com
# mp.jwt.token.header=Authorization
@@ -28,7 +38,11 @@ quarkus.log.level=INFO
# smallrye.jwt.sign.key.algorithm=RS256
# smallrye.jwt.token.lifetime=3600
# Activer le support multipart
# Activer le support multipart pour l'upload de fichiers
quarkus.http.body.uploads-directory=/tmp/uploads
quarkus.http.body.multipart.max-file-size=10M
quarkus.http.body.multipart.max-request-size=15M
# Taille maximale pour la requ<71>te multipart (en octets)
quarkus.http.body.multipart.max-request-size=10M
# Taille maximale pour un fichier multipart (en octets)
quarkus.http.body.multipart.max-file-size=5M