StatsController.java
package com.archiweb.api;
import com.archiweb.dto.StatsResponse;
import com.archiweb.service.StatsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/stats")
@Tag(
name = "Statistiques",
description = """
Regroupe toutes les statistiques globales du jeu concours :
- Codes : utilisés, restants et expirés
- Participations : totales, réclamées, non réclamées
- Gains : répartition par type de lot
- Données démographiques : âge moyen, consentement, etc.
"""
)
public class StatsController {
private final StatsService statsService;
public StatsController(StatsService statsService) {
this.statsService = statsService;
}
// ==============================
// 1️⃣ - Statistiques globales filtrées
// ==============================
@Operation(
summary = "Obtenir les statistiques globales filtrées",
description = """
Permet de récupérer les statistiques du jeu en filtrant selon :
- lot (type de lot, ex: INFUSEUR)
- boutique (nom ou ID du point de vente)
- période (format libre : '2025-01', 'S1-2025', etc.)
""",
responses = {
@ApiResponse(responseCode = "200", description = "Statistiques récupérées avec succès",
content = @Content(
schema = @Schema(implementation = StatsResponse.class),
examples = @ExampleObject(value = """
{
"totalCodes": 500000,
"codesUtilises": 200000,
"codesNonUtilises": 300000,
"codesExpires": 5000,
"totalParticipations": 150000,
"participationsReclamees": 140000,
"participationsNonReclamees": 10000,
"repartitionLots": {
"INFUSEUR": 300000,
"DETOX_100G": 100000,
"SIGNATURE_100G": 50000
}
}
""")
)
),
@ApiResponse(responseCode = "400", description = "Paramètres invalides"),
@ApiResponse(responseCode = "401", description = "Jeton JWT manquant ou invalide")
}
)
@GetMapping
public StatsResponse getStats(
@Parameter(description = "Type de lot à filtrer (ex: INFUSEUR, DETOX_100G)")
@RequestParam(required = false) String lot,
@Parameter(description = "Nom de la boutique ou identifiant du point de vente")
@RequestParam(required = false) String boutique,
@Parameter(description = "Période (format libre : '2025-01', 'S1-2025', etc.)")
@RequestParam(required = false) String periode) {
return statsService.getStats(lot, boutique, periode);
}
// ==============================
// 2️⃣ - Statistiques globales simples
// ==============================
@Operation(
summary = "Obtenir les statistiques globales (sans filtres)",
description = "Renvoie les statistiques générales du jeu sans appliquer de filtres.",
responses = {
@ApiResponse(responseCode = "200", description = "Statistiques globales récupérées avec succès")
}
)
@GetMapping("/global")
public StatsResponse getGlobalStats() {
return statsService.getStats();
}
// ==============================
// 3️⃣ - Statistiques démographiques
// ==============================
@Operation(
summary = "Obtenir les statistiques démographiques",
description = "Renvoie des informations démographiques sur les participants : âge moyen, consentements, etc.",
responses = {
@ApiResponse(responseCode = "200", description = "Statistiques démographiques récupérées avec succès",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(value = """
{
"totalUsers": 12450,
"averageAge": 31.7,
"consentGiven": 9870
}
""")
)
)
}
)
@GetMapping("/demographics")
public ResponseEntity<Map<String, Object>> getDemographics() {
Map<String, Object> data = statsService.getDemographicStats();
return ResponseEntity.ok(data);
}
// ==============================
// 4️⃣ - Statistiques des gains
// ==============================
@Operation(
summary = "Obtenir les statistiques des gains",
description = "Retourne la répartition du nombre de lots gagnés par type (INFUSEUR, DETOX_100G, etc.).",
responses = {
@ApiResponse(responseCode = "200", description = "Statistiques des gains récupérées avec succès",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(value = """
{
"INFUSEUR": 300000,
"DETOX_100G": 100000,
"SIGNATURE_100G": 50000,
"COFFRET_39": 30000,
"COFFRET_69": 20000
}
""")
)
)
}
)
@GetMapping("/wins")
public ResponseEntity<Map<String, Long>> getWinsStats() {
Map<String, Long> stats = statsService.getWinsStats();
return ResponseEntity.ok(stats);
}
// ==============================
// 5️⃣ - Statistiques des codes
// ==============================
@Operation(
summary = "Obtenir les statistiques des codes",
description = "Renvoie la répartition des codes selon leur état : utilisés, restants et expirés.",
responses = {
@ApiResponse(responseCode = "200", description = "Statistiques des codes récupérées avec succès",
content = @Content(
mediaType = "application/json",
examples = @ExampleObject(value = """
{
"totalCodes": 500000,
"usedCodes": 200000,
"unusedCodes": 295000,
"expiredCodes": 5000
}
""")
)
)
}
)
@GetMapping("/codes")
public ResponseEntity<Map<String, Long>> getCodesStats() {
Map<String, Long> stats = statsService.getCodesStats();
return ResponseEntity.ok(stats);
}
}