using System;
using System.Linq;
using System.Threading.Tasks;
using ManagerService.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace ManagerService.Services
{
///
/// Purge le journal d'audit au-delà de .
///
/// ⚠️ **C'est un sujet RGPD, et rien d'autre.** `AuditLog` porte un `UserId`, et les
/// valeurs avant/après d'une modification de `User` contiennent e-mail, prénom et nom —
/// conservés sans limite jusqu'ici, alors que `VisitEvent` purge à 13 mois et
/// `VisitorQuestion` à 90 jours. **Ce n'est pas un sujet de volume** : depuis que le flot
/// machine de `WeatherSyncService` est coupé (2026-08-12), la table ne croît qu'au rythme
/// des éditions humaines.
///
/// **12 mois, uniforme.** Pas 13 : les 13 mois des statistiques existent pour comparer une
/// saison à la précédente, et recopier ce chiffre ici serait du mimétisme. ⛔ Écarté aussi :
/// garder les suppressions plus longtemps que les créations et modifications — ça double
/// les règles pour un cas qu'une sauvegarde couvre déjà.
///
/// ⚠️ **Inerte tant que Audit:RetentionDays n'est pas défini**, exactement comme
/// et pour la même raison : c'est une suppression
/// définitive, et le pg_dump quotidien n'est toujours pas en place. Supprimer des lignes
/// d'audit sans restauration fine est la pire combinaison possible.
///
/// ⛔ Ne pas s'aligner sur , qui tourne sans
/// condition : ses 90 jours sont un engagement écrit dans les CGU, pas un réglage
/// d'exploitation. Ici, aucun contrat ne fixe la durée.
///
public class AuditLogPurgeService
{
/// Durée recommandée. Voir le lot J du plan V1.
public const int DefaultRetentionDays = 365;
private readonly MyInfoMateDbContext _dbContext;
private readonly IConfiguration _configuration;
private readonly ILogger _logger;
public AuditLogPurgeService(
MyInfoMateDbContext dbContext,
IConfiguration configuration,
ILogger logger)
{
_dbContext = dbContext;
_configuration = configuration;
_logger = logger;
}
public async Task PurgeAsync()
{
var retentionDays = _configuration.GetValue("Audit:RetentionDays");
if (retentionDays <= 0)
{
_logger.LogInformation(
"Purge du journal d'audit ignorée : Audit:RetentionDays non défini. " +
"Valeur attendue une fois le pg_dump en place : {Expected}.",
DefaultRetentionDays);
return;
}
var cutoff = DateTime.UtcNow.AddDays(-retentionDays);
var deleted = await _dbContext.AuditLogs
.Where(a => a.Timestamp < cutoff)
.ExecuteDeleteAsync();
_logger.LogInformation(
"Purge du journal d'audit : {Deleted} entrée(s) antérieure(s) au {Cutoff:yyyy-MM-dd} supprimée(s).",
deleted, cutoff);
}
}
}