Versions stable (inachevée mais prête à un déploiement en prod)

This commit is contained in:
DahoudG
2024-12-15 16:35:50 +00:00
parent a276ac2318
commit d2cb9da730
126 changed files with 13559 additions and 631 deletions

View File

@@ -0,0 +1,264 @@
package dev.lions.repositories;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import jakarta.transaction.Transactional;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import dev.lions.events.AnalyticsEvent;
import dev.lions.exceptions.RepositoryException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* Repository gérant la persistance des événements analytiques.
* Cette classe assure le stockage, la récupération et l'analyse
* des événements analytiques de l'application.
*
* @author Lions Dev Team
* @version 1.1
*/
@Slf4j
@ApplicationScoped
public class AnalyticsRepository extends BaseRepository<AnalyticsEvent, Long> {
@PersistenceContext
private EntityManager entityManager;
/**
* Recherche tous les événements pour une période donnée.
*
* @param startDate Date de début de la période
* @param endDate Date de fin de la période
* @return Liste des événements trouvés
* @throws RepositoryException En cas d'erreur de requête
*/
public List<AnalyticsEvent> findEventsByDateRange(@NotNull LocalDateTime startDate,
@NotNull LocalDateTime endDate) {
log.debug("Recherche des événements entre {} et {}", startDate, endDate);
try {
TypedQuery<AnalyticsEvent> query = entityManager.createQuery(
"SELECT e FROM AnalyticsEvent e " +
"WHERE e.timestamp BETWEEN :startDate AND :endDate " +
"ORDER BY e.timestamp DESC",
AnalyticsEvent.class);
query.setParameter("startDate", startDate);
query.setParameter("endDate", endDate);
List<AnalyticsEvent> events = query.getResultList();
log.info("Trouvé {} événements pour la période demandée", events.size());
return events;
} catch (Exception e) {
log.error("Erreur lors de la recherche des événements par période", e);
throw new RepositoryException(
"Erreur lors de la recherche des événements par période", e);
}
}
/**
* Recherche les événements analytiques par type pour une période donnée.
*
* @param eventType Type d'événement recherché
* @param startDate Date de début
* @param endDate Date de fin
* @return Liste des événements trouvés
*/
public List<AnalyticsEvent> findEventsByType(@NotNull String eventType,
@NotNull LocalDateTime startDate,
@NotNull LocalDateTime endDate) {
log.debug("Recherche des événements de type {} entre {} et {}",
eventType, startDate, endDate);
try {
TypedQuery<AnalyticsEvent> query = entityManager.createQuery(
"SELECT e FROM AnalyticsEvent e " +
"WHERE e.eventType = :eventType " +
"AND e.timestamp BETWEEN :startDate AND :endDate " +
"ORDER BY e.timestamp DESC",
AnalyticsEvent.class);
query.setParameter("eventType", eventType);
query.setParameter("startDate", startDate);
query.setParameter("endDate", endDate);
return query.getResultList();
} catch (Exception e) {
throw new RepositoryException(
"Erreur lors de la recherche des événements par type", e);
}
}
/**
* Enregistre un nouvel événement analytique.
*
* @param event Événement à sauvegarder
* @return Événement sauvegardé
*/
@Transactional
public AnalyticsEvent save(AnalyticsEvent event) {
log.debug("Sauvegarde d'un nouvel événement de type: {}", event.getEventType());
try {
if (event.getId() == null) {
entityManager.persist(event);
log.info("Nouvel événement créé avec l'ID: {}", event.getId());
} else {
event = entityManager.merge(event);
log.info("Événement mis à jour avec l'ID: {}", event.getId());
}
return event;
} catch (Exception e) {
log.error("Erreur lors de la sauvegarde de l'événement", e);
throw new RepositoryException("Erreur lors de la sauvegarde de l'événement", e);
}
}
/**
* Calcule le nombre d'événements par type pour une période donnée.
*
* @param startDate Date de début
* @param endDate Date de fin
* @return Map des compteurs par type d'événement
*/
public Map<String, Long> getEventCountByType(@NotNull LocalDateTime startDate,
@NotNull LocalDateTime endDate) {
log.debug("Calcul du nombre d'événements entre {} et {}", startDate, endDate);
try {
List<Object[]> results = entityManager.createQuery(
"SELECT e.eventType, COUNT(e) FROM AnalyticsEvent e " +
"WHERE e.timestamp BETWEEN :startDate AND :endDate " +
"GROUP BY e.eventType ORDER BY COUNT(e) DESC",
Object[].class)
.setParameter("startDate", startDate)
.setParameter("endDate", endDate)
.getResultList();
return results.stream()
.collect(Collectors.toMap(
row -> (String) row[0],
row -> (Long) row[1]
));
} catch (Exception e) {
throw new RepositoryException(
"Erreur lors du calcul du nombre d'événements", e);
}
}
/**
* Recherche les événements associés à un contact spécifique.
*
* @param contactId Identifiant du contact
* @return Liste des événements associés
*/
public List<AnalyticsEvent> findEventsByContactId(@NotNull String contactId) {
log.debug("Recherche des événements pour le contact {}", contactId);
try {
TypedQuery<AnalyticsEvent> query = entityManager.createQuery(
"SELECT e FROM AnalyticsEvent e " +
"WHERE e.contactId = :contactId " +
"ORDER BY e.timestamp DESC",
AnalyticsEvent.class);
query.setParameter("contactId", contactId);
return query.getResultList();
} catch (Exception e) {
throw new RepositoryException(
"Erreur lors de la recherche des événements par contact", e);
}
}
/**
* Supprime les événements antérieurs à une date donnée.
*
* @param retentionDate Date limite de conservation
* @return Nombre d'événements supprimés
*/
@Transactional
public int deleteEventsOlderThan(@NotNull LocalDateTime retentionDate) {
log.info("Suppression des événements antérieurs à {}", retentionDate);
try {
int deletedCount = entityManager.createQuery(
"DELETE FROM AnalyticsEvent e WHERE e.timestamp < :retentionDate")
.setParameter("retentionDate", retentionDate)
.executeUpdate();
log.info("{} événements supprimés", deletedCount);
return deletedCount;
} catch (Exception e) {
throw new RepositoryException(
"Erreur lors de la suppression des anciens événements", e);
}
}
/**
* Recherche un événement par son identifiant.
*
* @param id Identifiant de l'événement
* @return Optional contenant l'événement s'il existe
*/
public Optional<AnalyticsEvent> findById(Long id) {
log.debug("Recherche de l'événement avec l'ID: {}", id);
try {
AnalyticsEvent event = entityManager.find(AnalyticsEvent.class, id);
return Optional.ofNullable(event);
} catch (Exception e) {
throw new RepositoryException(
"Erreur lors de la recherche de l'événement par ID", e);
}
}
/**
* Calcule les statistiques d'événements par environnement.
*
* @param startDate Date de début
* @param endDate Date de fin
* @return Map des statistiques par environnement
*/
public Map<String, Long> getEventStatistics(LocalDateTime startDate,
LocalDateTime endDate) {
log.debug("Calcul des statistiques entre {} et {}", startDate, endDate);
try {
List<Object[]> results = entityManager.createQuery(
"SELECT e.environment, COUNT(e) FROM AnalyticsEvent e " +
"WHERE e.timestamp BETWEEN :startDate AND :endDate " +
"GROUP BY e.environment",
Object[].class)
.setParameter("startDate", startDate)
.setParameter("endDate", endDate)
.getResultList();
return results.stream()
.collect(Collectors.toMap(
row -> (String) row[0],
row -> (Long) row[1]
));
} catch (Exception e) {
throw new RepositoryException(
"Erreur lors du calcul des statistiques", e);
}
}
}