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);
}
}
}