using System.Security.Claims; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using ROLAC.API.Entities.Base; namespace ROLAC.API.Data.Interceptors; public class AuditSaveChangesInterceptor : SaveChangesInterceptor { private readonly IHttpContextAccessor _http; public AuditSaveChangesInterceptor(IHttpContextAccessor http) => _http = http; public override InterceptionResult SavingChanges( DbContextEventData eventData, InterceptionResult result) { Stamp(eventData.Context); return base.SavingChanges(eventData, result); } public override ValueTask> SavingChangesAsync( DbContextEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) { Stamp(eventData.Context); return base.SavingChangesAsync(eventData, result, cancellationToken); } private void Stamp(DbContext? db) { if (db is null) return; var userId = _http.HttpContext?.User .FindFirstValue(ClaimTypes.NameIdentifier) ?? "system"; var now = DateTimeOffset.UtcNow; foreach (var entry in db.ChangeTracker.Entries()) { if (entry.Entity is not AuditableEntity audit) continue; if (entry.State == EntityState.Added) { audit.CreatedAt = now; audit.CreatedBy = userId; audit.UpdatedAt = now; audit.UpdatedBy = userId; } else if (entry.State == EntityState.Modified) { audit.UpdatedAt = now; audit.UpdatedBy = userId; } } } }