using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate; using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects; using ColaFlow.Shared.Kernel.Common; namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence.Configurations; /// /// Entity configuration for Story entity /// public class StoryConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { builder.ToTable("Stories"); // Primary key builder.HasKey("Id"); // Id conversion builder.Property(s => s.Id) .HasConversion( id => id.Value, value => StoryId.From(value)) .IsRequired() .ValueGeneratedNever(); // EpicId (foreign key) builder.Property(s => s.EpicId) .HasConversion( id => id.Value, value => EpicId.From(value)) .IsRequired(); // Basic properties builder.Property(s => s.Title) .HasMaxLength(200) .IsRequired(); builder.Property(s => s.Description) .HasMaxLength(4000); // Status enumeration builder.Property(s => s.Status) .HasConversion( st => st.Name, name => Enumeration.FromDisplayName(name)) .HasMaxLength(50) .IsRequired(); // Priority enumeration builder.Property(s => s.Priority) .HasConversion( p => p.Name, name => Enumeration.FromDisplayName(name)) .HasMaxLength(50) .IsRequired(); // CreatedBy conversion builder.Property(s => s.CreatedBy) .HasConversion( id => id.Value, value => UserId.From(value)) .IsRequired(); // AssigneeId (optional) builder.Property(s => s.AssigneeId) .HasConversion( id => id != null ? id.Value : (Guid?)null, value => value.HasValue ? UserId.From(value.Value) : null); // Effort tracking builder.Property(s => s.EstimatedHours); builder.Property(s => s.ActualHours); // Timestamps builder.Property(s => s.CreatedAt) .IsRequired(); builder.Property(s => s.UpdatedAt); // Ignore navigation properties (DDD pattern - access through aggregate) builder.Ignore(s => s.Tasks); // Foreign key relationship to Epic builder.HasOne() .WithMany() .HasForeignKey(s => s.EpicId) .OnDelete(DeleteBehavior.Cascade); // Indexes builder.HasIndex(s => s.EpicId); builder.HasIndex(s => s.AssigneeId); builder.HasIndex(s => s.CreatedAt); } }