using System.Data.Common; using Finbuckle.MultiTenant; using Finbuckle.MultiTenant.Abstractions; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; using Npgsql; namespace WorkClub.Infrastructure.Data.Interceptors; public class TenantDbConnectionInterceptor : DbConnectionInterceptor { private readonly IMultiTenantContextAccessor _tenantAccessor; private readonly ILogger _logger; public TenantDbConnectionInterceptor( IMultiTenantContextAccessor tenantAccessor, ILogger logger) { _tenantAccessor = tenantAccessor; _logger = logger; } public override async ValueTask ConnectionOpeningAsync( DbConnection connection, ConnectionEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) { await base.ConnectionOpeningAsync(connection, eventData, result, cancellationToken); var tenantId = _tenantAccessor.MultiTenantContext?.TenantInfo?.Identifier; if (string.IsNullOrWhiteSpace(tenantId)) { _logger.LogWarning("No tenant context available for database connection"); return result; } if (connection is NpgsqlConnection npgsqlConnection) { await using var command = npgsqlConnection.CreateCommand(); command.CommandText = $"SET LOCAL app.current_tenant_id = '{tenantId}'"; try { await command.ExecuteNonQueryAsync(cancellationToken); _logger.LogDebug("Set tenant context for database connection: {TenantId}", tenantId); } catch (Exception ex) { _logger.LogError(ex, "Failed to set tenant context for connection"); throw; } } return result; } public override void ConnectionOpened(DbConnection connection, ConnectionEndEventData eventData) { base.ConnectionOpened(connection, eventData); var tenantId = _tenantAccessor.MultiTenantContext?.TenantInfo?.Identifier; if (string.IsNullOrWhiteSpace(tenantId)) { _logger.LogWarning("No tenant context available for database connection"); return; } if (connection is NpgsqlConnection npgsqlConnection) { using var command = npgsqlConnection.CreateCommand(); command.CommandText = $"SET LOCAL app.current_tenant_id = '{tenantId}'"; try { command.ExecuteNonQuery(); _logger.LogDebug("Set tenant context for database connection: {TenantId}", tenantId); } catch (Exception ex) { _logger.LogError(ex, "Failed to set tenant context for connection"); throw; } } } }