using Microsoft.EntityFrameworkCore.Migrations; #nullable disable namespace ClaudeDo.Data.Migrations { /// /// Turns the single tasks.depends_on_task_id column into a set: one row per declared /// "run after" edge in task_dependencies. Hand-edited after scaffolding so the data copy /// sits between CreateTable and DropColumn — the scaffolded order dropped the column first and /// would have discarded every existing link. /// public partial class AddTaskDependencies : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) { migrationBuilder.CreateTable( name: "task_dependencies", columns: table => new { task_id = table.Column(type: "TEXT", nullable: false), depends_on_task_id = table.Column(type: "TEXT", nullable: false) }, constraints: table => { table.PrimaryKey("PK_task_dependencies", x => new { x.task_id, x.depends_on_task_id }); table.ForeignKey( name: "FK_task_dependencies_tasks_depends_on_task_id", column: x => x.depends_on_task_id, principalTable: "tasks", principalColumn: "id", onDelete: ReferentialAction.Cascade); table.ForeignKey( name: "FK_task_dependencies_tasks_task_id", column: x => x.task_id, principalTable: "tasks", principalColumn: "id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateIndex( name: "idx_task_dependencies_depends_on", table: "task_dependencies", column: "depends_on_task_id"); // Every existing link becomes a one-element set. The old FK was ON DELETE SET NULL, so // a surviving value always points at an existing task and can't violate the new FK. migrationBuilder.Sql(""" INSERT INTO task_dependencies (task_id, depends_on_task_id) SELECT id, depends_on_task_id FROM tasks WHERE depends_on_task_id IS NOT NULL """); migrationBuilder.DropForeignKey( name: "FK_tasks_tasks_depends_on_task_id", table: "tasks"); migrationBuilder.DropIndex( name: "idx_tasks_depends_on", table: "tasks"); migrationBuilder.DropColumn( name: "depends_on_task_id", table: "tasks"); } /// protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.AddColumn( name: "depends_on_task_id", table: "tasks", type: "TEXT", nullable: true); // Inherently lossy: a task with several predecessors keeps only one. There is no // single-column shape that could hold the rest. migrationBuilder.Sql(""" UPDATE tasks SET depends_on_task_id = ( SELECT td.depends_on_task_id FROM task_dependencies td WHERE td.task_id = tasks.id ORDER BY td.depends_on_task_id LIMIT 1 ) """); migrationBuilder.DropTable( name: "task_dependencies"); migrationBuilder.CreateIndex( name: "idx_tasks_depends_on", table: "tasks", column: "depends_on_task_id"); migrationBuilder.AddForeignKey( name: "FK_tasks_tasks_depends_on_task_id", table: "tasks", column: "depends_on_task_id", principalTable: "tasks", principalColumn: "id", onDelete: ReferentialAction.SetNull); } } }