using Domain.Entities.Members; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace Infrastructure.Persistence.Configurations.Members; public sealed class MemberTrackRecordConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.HasOne(x => x.Member).WithOne().HasForeignKey(x => x.MemberID).OnDelete(DeleteBehavior.Cascade); builder.ToTable(nameof(MemberTrackRecord), x => x.HasComment("회원 예측 트랙레코드 집계 (적중률 배지·리더보드)")); builder.HasKey(x => x.MemberID); builder.Property(x => x.MemberID).ValueGeneratedNever().HasComment("회원 ID (PK)"); builder.Property(x => x.Predictions).IsRequired().HasComment("채점 완료 예측 총계 (Hits+Misses+Voids)"); builder.Property(x => x.Hits).IsRequired().HasComment("적중 수"); builder.Property(x => x.Misses).IsRequired().HasComment("실패 수"); builder.Property(x => x.Voids).IsRequired().HasComment("무효 수 (표본 제외)"); builder.Property(x => x.HitRate).HasPrecision(5, 2).IsRequired().HasComment("적중률 % (Hits/(Hits+Misses)*100)"); builder.Property(x => x.CurrentStreak).IsRequired().HasComment("현재 연속 적중"); builder.Property(x => x.BestStreak).IsRequired().HasComment("역대 최고 연속 적중"); builder.Property(x => x.Tier).HasConversion().IsRequired().HasComment("배지 등급 (0=None/1=Bronze/2=Silver/3=Gold/4=GoldAnt)"); builder.Property(x => x.UpdatedAt).IsRequired().HasComment("갱신 일시"); // 리더보드 — 표본(채점 완료) 10+ 회원만 HitRate 내림차순 조회 (d2 §③). 필터 인덱스로 스캔 최소화. builder.HasIndex(x => x.HitRate).IsDescending().HasDatabaseName("IX_MemberTrackRecord_HitRate").HasFilter("[Predictions] >= 10"); } }