Files
Yaojia Wang 014d62bcc2 Project Init
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 23:55:18 +01:00

98 lines
2.9 KiB
C#

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;
/// <summary>
/// Entity configuration for Story entity
/// </summary>
public class StoryConfiguration : IEntityTypeConfiguration<Story>
{
public void Configure(EntityTypeBuilder<Story> 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<WorkItemStatus>(name))
.HasMaxLength(50)
.IsRequired();
// Priority enumeration
builder.Property(s => s.Priority)
.HasConversion(
p => p.Name,
name => Enumeration.FromDisplayName<TaskPriority>(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<Epic>()
.WithMany()
.HasForeignKey(s => s.EpicId)
.OnDelete(DeleteBehavior.Cascade);
// Indexes
builder.HasIndex(s => s.EpicId);
builder.HasIndex(s => s.AssigneeId);
builder.HasIndex(s => s.CreatedAt);
}
}