using System.Security.Claims; namespace JobTrackerApi.Services; public interface ICurrentUserService { string? UserId { get; } } public sealed class CurrentUserService : ICurrentUserService { private readonly IHttpContextAccessor _http; private string? _backgroundUserId; public CurrentUserService(IHttpContextAccessor http) { _http = http; } public string? UserId => _backgroundUserId ?? LocalAuthIdentity.GetRequiredUserId(_http.HttpContext?.User); public IDisposable UseBackgroundUser(string userId) { if (string.IsNullOrWhiteSpace(userId)) throw new ArgumentException("A background owner is required.", nameof(userId)); if (_http.HttpContext is not null) throw new InvalidOperationException("Background owner scope cannot replace an HTTP request identity."); var previous = _backgroundUserId; _backgroundUserId = userId; return new Reset(() => _backgroundUserId = previous); } private sealed class Reset(Action reset) : IDisposable { private Action? _reset = reset; public void Dispose() => Interlocked.Exchange(ref _reset, null)?.Invoke(); } }