using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace Nuuru.Server.Data.EntityConfigurations { public class PostConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.HasIndex(p => p.ImageHash) .IsUnique(); // Search indexes builder.HasIndex(p => p.UploadedAt); builder.HasIndex(p => p.Rating); builder.HasIndex(p => p.Category); builder.HasIndex(p => p.MimeType); // Composite index for common search patterns builder.HasIndex(p => new { p.Rating, p.UploadedAt }); // Approval indexes builder.HasIndex(p => p.IsApproved); builder.HasIndex(p => new { p.IsApproved, p.UploadedAt }); // User posts index (for /user/{username}/posts queries) builder.HasIndex(p => p.UploaderId); builder.HasIndex(p => new { p.UploaderId, p.UploadedAt }); // Pending posts index (unapproved + not trashed, ordered by upload date) builder.HasIndex(p => new { p.IsApproved, p.IsTrashed, p.UploadedAt }); // Featured post index — covers WHERE IsFeatured AND IsApproved AND NOT IsTrashed builder.HasIndex(p => new { p.IsFeatured, p.IsApproved, p.IsTrashed }); // Boost index — used for sort priority in search results builder.HasIndex(p => p.BoostedUntil); // Trash indexes builder.HasIndex(p => p.IsTrashed); builder.HasIndex(p => new { p.IsTrashed, p.TrashedAt }); // TrashedBy FK builder.HasOne(p => p.TrashedBy) .WithMany() .HasForeignKey(p => p.TrashedById) .OnDelete(DeleteBehavior.SetNull); // ApprovedBy FK builder.HasOne(p => p.ApprovedBy) .WithMany() .HasForeignKey(p => p.ApprovedById) .OnDelete(DeleteBehavior.SetNull); builder.HasMany(p => p.Comments) .WithOne(c => c.Post) .OnDelete(DeleteBehavior.Cascade); } } }