using System.Reflection; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate; using ColaFlow.Modules.ProjectManagement.Domain.Entities; using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects; namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence; /// /// Project Management Module DbContext /// public class PMDbContext : DbContext { private readonly IHttpContextAccessor _httpContextAccessor; public PMDbContext(DbContextOptions options, IHttpContextAccessor httpContextAccessor) : base(options) { _httpContextAccessor = httpContextAccessor; } public DbSet Projects => Set(); public DbSet Epics => Set(); public DbSet Stories => Set(); public DbSet Tasks => Set(); public DbSet Sprints => Set(); public DbSet AuditLogs => Set(); protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Set default schema for this module (must be before configurations) modelBuilder.HasDefaultSchema("project_management"); // Apply all entity configurations from this assembly modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); // Multi-tenant Global Query Filters modelBuilder.Entity().HasQueryFilter(p => p.TenantId == GetCurrentTenantId()); modelBuilder.Entity().HasQueryFilter(e => e.TenantId == GetCurrentTenantId()); modelBuilder.Entity().HasQueryFilter(s => s.TenantId == GetCurrentTenantId()); modelBuilder.Entity().HasQueryFilter(t => t.TenantId == GetCurrentTenantId()); modelBuilder.Entity().HasQueryFilter(s => s.TenantId == GetCurrentTenantId()); modelBuilder.Entity().HasQueryFilter(a => a.TenantId == GetCurrentTenantId()); } private TenantId GetCurrentTenantId() { var tenantIdClaim = _httpContextAccessor?.HttpContext?.User .FindFirst("tenant_id")?.Value; if (Guid.TryParse(tenantIdClaim, out var tenantId) && tenantId != Guid.Empty) { return TenantId.From(tenantId); } // Return a dummy value for queries outside HTTP context (e.g., migrations) // These will return no results due to the filter return TenantId.From(Guid.Empty); } }