RgpdController.java
package com.archiweb.api;
import com.archiweb.model.User;
import com.archiweb.model.Win;
import com.archiweb.repository.UserRepository;
import com.archiweb.repository.WinRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.*;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/api/rgpd")
@RequiredArgsConstructor
@Tag(
name = "RGPD / Confidentialité",
description = """
Module de gestion des **données personnelles** des utilisateurs conformément au RGPD.
Ce contrôleur permet :
- L’**exportation complète** des données personnelles d’un utilisateur (profil et historique des gains).
- La **suppression totale** d’un compte utilisateur et de ses données associées (droit à l’oubli).
Accessible aux utilisateurs souhaitant exercer leur droit à la portabilité ou à la suppression de leurs données.
"""
)
public class RgpdController {
private final UserRepository userRepository;
private final WinRepository winRepository;
// =========================================================
// 1️⃣ Exportation des données personnelles
// =========================================================
@Operation(
summary = "Exporter les données personnelles d’un utilisateur",
description = """
Permet à un utilisateur d’obtenir une **copie complète de ses données personnelles** enregistrées dans la base.
L’export comprend :
- Les informations du profil (identité, email, consentement, etc.)
- L’historique de ses gains enregistrés dans le système.
""",
responses = {
@ApiResponse(
responseCode = "200",
description = "Exportation effectuée avec succès",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(
value = """
{
"id": 5,
"username": "karim_aitb",
"email": "karim@example.com",
"firstName": "Karim",
"lastName": "Ait Bouaddi",
"phone": "+33612345678",
"birthDate": "1990-05-20",
"consentGiven": true,
"createdAt": "2024-03-10T10:15:45",
"updatedAt": "2025-10-25T14:12:00",
"wins": [
"INFUSEUR",
"COFFRET_99"
]
}
"""
)
)
),
@ApiResponse(
responseCode = "404",
description = "Utilisateur introuvable",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(value = "{ \"error\": \"Utilisateur introuvable.\" }")
)
)
}
)
@GetMapping("/users/{id}/export")
public ResponseEntity<?> exportUserData(@PathVariable Long id) {
Optional<User> optionalUser = userRepository.findById(id);
if (optionalUser.isEmpty()) {
return ResponseEntity.status(404).body("Utilisateur introuvable.");
}
User user = optionalUser.get();
List<Win> wins = winRepository.findByUserId(id);
Map<String, Object> export = new LinkedHashMap<>();
export.put("id", user.getId());
export.put("username", user.getUsername());
export.put("email", user.getEmail());
export.put("firstName", user.getFirstName());
export.put("lastName", user.getLastName());
export.put("phone", user.getPhone());
export.put("birthDate", user.getBirthDate());
export.put("consentGiven", user.isConsentGiven());
export.put("createdAt", user.getCreatedAt());
export.put("updatedAt", user.getUpdatedAt());
export.put("wins", wins.stream().map(Win::getPrizeName).collect(Collectors.toList()));
return ResponseEntity.ok(export);
}
// =========================================================
// 2️⃣ Suppression complète du compte utilisateur
// =========================================================
@Operation(
summary = "Supprimer un compte utilisateur et ses données associées",
description = """
Permet d’exercer le **droit à l’oubli** : supprime définitivement le compte utilisateur et toutes les données associées (gains, informations personnelles).
Une fois cette opération effectuée, aucune restauration n’est possible.
""",
responses = {
@ApiResponse(
responseCode = "200",
description = "Compte supprimé avec succès",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(
value = """
{
"status": "success",
"message": "Compte utilisateur supprimé avec succès (droit à l’oubli exercé).",
"deletedUser": "karim@example.com"
}
"""
)
)
),
@ApiResponse(
responseCode = "404",
description = "Utilisateur introuvable",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(value = "{ \"error\": \"Utilisateur introuvable.\" }")
)
)
}
)
@DeleteMapping("/users/{id}/delete")
public ResponseEntity<?> deleteUserAndData(@PathVariable Long id) {
Optional<User> optionalUser = userRepository.findById(id);
if (optionalUser.isEmpty()) {
return ResponseEntity.status(404).body("Utilisateur introuvable.");
}
User user = optionalUser.get();
List<Win> userWins = winRepository.findByUserId(id);
if (!userWins.isEmpty()) {
winRepository.deleteAll(userWins);
}
userRepository.delete(user);
return ResponseEntity.ok(
Map.of(
"status", "success",
"message", "Compte utilisateur supprimé avec succès (droit à l’oubli exercé).",
"deletedUser", user.getEmail()
)
);
}
}