using System.Security.Claims; using Jiaowu.Api.Domain.System; using Jiaowu.Api.Infrastructure.Persistence; namespace Jiaowu.Api.Infrastructure.Middleware; public sealed class AuditMiddleware(RequestDelegate next) { public async Task InvokeAsync(HttpContext context, AppDbContext db) { await next(context); if (HttpMethods.IsGet(context.Request.Method) || context.Request.Path.StartsWithSegments("/swagger")) { return; } // A failed business write can leave invalid tracked entities in this request scope. // Audit persistence must not retry those entities and replace the original response. db.ChangeTracker.Clear(); db.AuditLogs.Add(new AuditLog { UserId = Guid.TryParse( context.User.FindFirstValue(ClaimTypes.NameIdentifier), out var userId) ? userId : null, UserName = context.User.Identity?.Name, Method = context.Request.Method, Path = context.Request.Path, StatusCode = context.Response.StatusCode, IpAddress = context.Connection.RemoteIpAddress?.ToString() }); await db.SaveChangesAsync(context.RequestAborted); } }