In progress
Some checks failed
Code Coverage / Generate Coverage Report (push) Has been cancelled
Tests / Run Tests (9.0.x) (push) Has been cancelled
Tests / Docker Build Test (push) Has been cancelled
Tests / Test Summary (push) Has been cancelled

This commit is contained in:
Yaojia Wang
2025-11-03 11:51:02 +01:00
parent 24fb646739
commit fe8ad1c1f9
101 changed files with 26471 additions and 250 deletions

View File

@@ -12,8 +12,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
{
[DbContext(typeof(PMDbContext))]
[Migration("20251102220422_InitialCreate")]
partial class InitialCreate
[Migration("20251103000604_FixValueObjectForeignKeys")]
partial class FixValueObjectForeignKeys
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -55,9 +55,6 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
b.Property<Guid>("ProjectId")
.HasColumnType("uuid");
b.Property<Guid?>("ProjectId1")
.HasColumnType("uuid");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
@@ -72,8 +69,6 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
b.HasIndex("ProjectId");
b.HasIndex("ProjectId1");
b.ToTable("Epics", "project_management");
});
@@ -232,14 +227,10 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Epic", b =>
{
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", null)
.WithMany()
.WithMany("Epics")
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", null)
.WithMany("Epics")
.HasForeignKey("ProjectId1");
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", b =>
@@ -273,7 +264,7 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Story", b =>
{
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Epic", null)
.WithMany()
.WithMany("Stories")
.HasForeignKey("EpicId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@@ -282,16 +273,26 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.WorkTask", b =>
{
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Story", null)
.WithMany()
.WithMany("Tasks")
.HasForeignKey("StoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Epic", b =>
{
b.Navigation("Stories");
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", b =>
{
b.Navigation("Epics");
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Story", b =>
{
b.Navigation("Tasks");
});
#pragma warning restore 612, 618
}
}

View File

@@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
public partial class FixValueObjectForeignKeys : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
@@ -46,8 +46,7 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
Priority = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
CreatedBy = table.Column<Guid>(type: "uuid", nullable: false),
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
ProjectId1 = table.Column<Guid>(type: "uuid", nullable: true)
UpdatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
},
constraints: table =>
{
@@ -59,12 +58,6 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
principalTable: "Projects",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_Epics_Projects_ProjectId1",
column: x => x.ProjectId1,
principalSchema: "project_management",
principalTable: "Projects",
principalColumn: "Id");
});
migrationBuilder.CreateTable(
@@ -139,12 +132,6 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
table: "Epics",
column: "ProjectId");
migrationBuilder.CreateIndex(
name: "IX_Epics_ProjectId1",
schema: "project_management",
table: "Epics",
column: "ProjectId1");
migrationBuilder.CreateIndex(
name: "IX_Projects_CreatedAt",
schema: "project_management",

View File

@@ -52,9 +52,6 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
b.Property<Guid>("ProjectId")
.HasColumnType("uuid");
b.Property<Guid?>("ProjectId1")
.HasColumnType("uuid");
b.Property<string>("Status")
.IsRequired()
.HasMaxLength(50)
@@ -69,8 +66,6 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
b.HasIndex("ProjectId");
b.HasIndex("ProjectId1");
b.ToTable("Epics", "project_management");
});
@@ -229,14 +224,10 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Epic", b =>
{
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", null)
.WithMany()
.WithMany("Epics")
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", null)
.WithMany("Epics")
.HasForeignKey("ProjectId1");
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", b =>
@@ -270,7 +261,7 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Story", b =>
{
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Epic", null)
.WithMany()
.WithMany("Stories")
.HasForeignKey("EpicId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
@@ -279,16 +270,26 @@ namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Migrations
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.WorkTask", b =>
{
b.HasOne("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Story", null)
.WithMany()
.WithMany("Tasks")
.HasForeignKey("StoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Epic", b =>
{
b.Navigation("Stories");
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Project", b =>
{
b.Navigation("Epics");
});
modelBuilder.Entity("ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate.Story", b =>
{
b.Navigation("Tasks");
});
#pragma warning restore 612, 618
}
}

View File

@@ -70,13 +70,11 @@ public class EpicConfiguration : IEntityTypeConfiguration<Epic>
builder.Property(e => e.UpdatedAt);
// Ignore navigation properties (DDD pattern - access through aggregate)
builder.Ignore(e => e.Stories);
// Foreign key relationship to Project
builder.HasOne<Project>()
.WithMany()
.HasForeignKey(e => e.ProjectId)
// Configure Stories collection (owned by Epic in the aggregate)
// Use string-based FK name because EpicId is a value object with conversion configured in StoryConfiguration
builder.HasMany<Story>("Stories")
.WithOne()
.HasForeignKey("EpicId")
.OnDelete(DeleteBehavior.Cascade);
// Indexes

View File

@@ -67,7 +67,12 @@ public class ProjectConfiguration : IEntityTypeConfiguration<Project>
builder.Property(p => p.UpdatedAt);
// Relationships - Epics collection (owned by aggregate)
// Note: We don't expose this as navigation property in DDD, epics are accessed through repository
// Configure the one-to-many relationship with Epic
// Use string-based FK name because ProjectId is a value object with conversion configured in EpicConfiguration
builder.HasMany<Epic>("Epics")
.WithOne()
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade);
// Indexes for performance
builder.HasIndex(p => p.CreatedAt);

View File

@@ -80,13 +80,11 @@ public class StoryConfiguration : IEntityTypeConfiguration<Story>
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)
// Configure Tasks collection (owned by Story in the aggregate)
// Use string-based FK name because StoryId is a value object with conversion configured in WorkTaskConfiguration
builder.HasMany<WorkTask>("Tasks")
.WithOne()
.HasForeignKey("StoryId")
.OnDelete(DeleteBehavior.Cascade);
// Indexes

View File

@@ -80,12 +80,6 @@ public class WorkTaskConfiguration : IEntityTypeConfiguration<WorkTask>
builder.Property(t => t.UpdatedAt);
// Foreign key relationship to Story
builder.HasOne<Story>()
.WithMany()
.HasForeignKey(t => t.StoryId)
.OnDelete(DeleteBehavior.Cascade);
// Indexes
builder.HasIndex(t => t.StoryId);
builder.HasIndex(t => t.AssigneeId);