using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using ColaFlow.Modules.ProjectManagement.Domain.Entities; using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects; namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence.Configurations; /// /// Entity configuration for AuditLog /// Configures multi-tenant isolation, JSONB columns, and composite indexes /// public class AuditLogConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ToTable("AuditLogs"); // Primary key builder.HasKey(a => a.Id); builder.Property(a => a.Id) .IsRequired() .ValueGeneratedNever(); // TenantId conversion (StronglyTypedId to Guid) builder.Property(a => a.TenantId) .HasConversion( id => id.Value, value => TenantId.From(value)) .IsRequired(); // EntityType - the type name of the entity being audited builder.Property(a => a.EntityType) .IsRequired() .HasMaxLength(100); // EntityId - the ID of the entity being audited builder.Property(a => a.EntityId) .IsRequired(); // Action - Create, Update, Delete builder.Property(a => a.Action) .IsRequired() .HasMaxLength(20); // UserId conversion (nullable StronglyTypedId to Guid) builder.Property(a => a.UserId) .HasConversion( id => id != null ? id.Value : (Guid?)null, value => value.HasValue ? UserId.From(value.Value) : null); // Timestamp with UTC builder.Property(a => a.Timestamp) .IsRequired(); // OldValues as JSONB (PostgreSQL-specific) builder.Property(a => a.OldValues) .HasColumnType("jsonb"); // NewValues as JSONB (PostgreSQL-specific) builder.Property(a => a.NewValues) .HasColumnType("jsonb"); // Composite index for efficient entity history queries // Query pattern: Get all audit logs for a specific entity within a tenant builder.HasIndex(a => new { a.TenantId, a.EntityType, a.EntityId }) .HasDatabaseName("IX_AuditLogs_TenantId_EntityType_EntityId"); // Index for recent logs queries (DESC order for performance) // Query pattern: Get most recent audit logs across all entities builder.HasIndex(a => a.Timestamp) .HasDatabaseName("IX_AuditLogs_Timestamp") .IsDescending(); // Index for user activity tracking // Query pattern: Get all actions performed by a specific user builder.HasIndex(a => a.UserId) .HasDatabaseName("IX_AuditLogs_UserId"); } }