diff --git a/src/ClaudeDo.Data/CLAUDE.md b/src/ClaudeDo.Data/CLAUDE.md
index f48f3a76..34e7dfe3 100644
--- a/src/ClaudeDo.Data/CLAUDE.md
+++ b/src/ClaudeDo.Data/CLAUDE.md
@@ -8,8 +8,8 @@ Shared data layer: models, repositories, SQLite infrastructure, and git operatio
- Status / PlanningPhase / BlockedByTaskId / DependsOnTaskId semantics + allowed transitions: `ClaudeDo.Worker/CLAUDE.md` → Status Model.
- `HandlerBaseCommit`/`HandlerHeadCommit` = the review range for a **worktree-less "list handler" host task** ("Let Claude handle it"), which commits straight into the list's working dir instead of a per-task worktree. Everything that reads a task's diff falls back to this pair whenever `Worktree` is null → [conpty-sessions](../../docs/explore-notes/conpty-sessions.md).
- `InteractiveSessionId` = the claude session id an embedded ConPTY interactive task session runs under, persisted by `InteractiveLaunchSpecService` before launch so a closed/aborted session can be resumed → [conpty-sessions](../../docs/explore-notes/conpty-sessions.md).
- - `Number` (INTEGER NOT NULL, unique index `idx_tasks_number`) — a global, monotonically increasing display alias for tasks. **Never reused**: deleting a task leaves a gap in numbering, ensuring that a task number that appears in a log or report always points to the same task (if it exists). Allocated by `TaskNumberAllocator.AddWithNumberAsync` on every insert via a persistent counter (`app_settings.next_task_number`). **Why not `MAX(number) + 1`:** deleting the highest-numbered task would free its number for reuse, breaking the immutability guarantee. The allocator uses an `UPDATE…RETURNING` statement to claim numbers atomically, retrying up to 5 times if a uniqueness collision occurs (the counter advances on each attempt, so retries always allocate fresh numbers). ⚠️ Tests use `EnsureCreated`, which bypasses migrations — the backfill needs a migration that runs `Migrate()` explicitly (not tested by default; see `worker-task-pipeline` notes).
- - Legacy status values `Manual`/`Planning`/`Planned`/`Draft`/`Waiting` were retired; existing rows backfill via the `RetireLegacyTaskStatus` migration.
+ - `Number` (INTEGER NOT NULL, unique index `idx_tasks_number`) — a global, monotonically increasing display alias for tasks. **Never reused**: deleting a task leaves a gap in numbering, ensuring that a task number that appears in a log or report always points to the same task (if it exists). Allocated by `TaskNumberAllocator.AddWithNumberAsync` on every insert via a persistent counter (`app_settings.next_task_number`). **Why not `MAX(number) + 1`:** deleting the highest-numbered task would free its number for reuse, breaking the immutability guarantee. The allocator uses an `UPDATE…RETURNING` statement to claim numbers atomically, retrying up to 5 times if a uniqueness collision occurs (the counter advances on each attempt, so retries always allocate fresh numbers). The one-time backfill for pre-existing rows lived in the `AddTaskNumbers` migration, squashed away 2026-08-26.
+ - Legacy status values `Manual`/`Planning`/`Planned`/`Draft`/`Waiting` were retired. The backfill migration was squashed away (2026-08-26) — a database still holding those values can't be upgraded, see Schema below.
- **ListEntity** — Id, Name, WorkingDir, DefaultCommitType, CreatedAt, IsManual (reminder list — tasks created here default to `IsManual`)
- **ListConfigEntity** — ListId (PK, 1:1), Model, SystemPrompt, AgentPath, MaxTurns, SessionSkills, VerifyCommand (all nullable). `VerifyCommand` is an optional post-merge gate; null/blank = no gate → [review-merge](../../docs/explore-notes/review-merge.md).
- **WorktreeEntity** — TaskId (PK, 1:1), Path, BranchName, BaseCommit, HeadCommit, DiffStat, MergeCommit (nullable — SHA of the merge commit this branch produced; the only thing making `revert_merge` possible without searching `git log`), State (`Active|Merged|Discarded|Kept`)
@@ -97,8 +97,19 @@ Tables (one per line so parallel migrations don't collide on the same line):
- `week_reports`
- `task_attachments`
-Managed by EF Core migrations in `Migrations/` — **`ls Migrations/` is the authoritative history**;
-don't maintain a changelog here. `tasks` holds `status`, `planning_phase` (default `none`),
+Managed by EF Core migrations in `Migrations/`. **The 40 incremental migrations were squashed into
+a single `20260826094154_InitialCreate` on 2026-08-26** — the schema history is git history now,
+not a migration chain. Consequences:
+
+- `ClaudeDoDbContext.MigrateAndConfigure` **baselines** an existing database onto the squashed id
+ (pre-EF databases without a history, and databases whose history still lists the old chain ending
+ at `20260825063230_AddPrimeActionKind`). A database that stopped *mid*-chain can no longer be
+ upgraded and throws with a reinstall message instead of being stamped onto a schema it lacks.
+ Covered by `MigrationBaselineTests` — the only test that runs a real `Migrate()` (every other
+ Data.Tests fixture uses `EnsureCreated`, which skips migrations entirely).
+- Don't hand-edit the migration; add new ones on top as usual.
+
+`tasks` holds `status`, `planning_phase` (default `none`),
`blocked_by_task_id` (FK to `tasks.id`, `ON DELETE SET NULL`), and `depends_on_task_id` (same FK
shape, but a separate column — see Worker/CLAUDE.md → Status Model for why it isn't unified with
`blocked_by_task_id`).
diff --git a/src/ClaudeDo.Data/ClaudeDoDbContext.cs b/src/ClaudeDo.Data/ClaudeDoDbContext.cs
index 7000dbd2..9e466fb4 100644
--- a/src/ClaudeDo.Data/ClaudeDoDbContext.cs
+++ b/src/ClaudeDo.Data/ClaudeDoDbContext.cs
@@ -73,11 +73,19 @@ public class ClaudeDoDbContext : DbContext
}
}
+ // The 40 incremental migrations were squashed into a single InitialCreate on 2026-08-26.
+ // Any database that already carries the full pre-squash schema has to be re-stamped to the
+ // squashed id, or Migrate() would run CREATE TABLE over live tables.
+ private const string SquashedMigrationId = "20260826094154_InitialCreate";
+ private const string LastPreSquashMigrationId = "20260825063230_AddPrimeActionKind";
+
///
/// Applies EF Core migrations and sets WAL mode. Safe for both fresh and existing databases.
- /// Existing databases (created by the old schema.sql) have their tables but no
- /// __EFMigrationsHistory — this method detects that case and baselines the initial
- /// migration so EF skips re-creating tables that already exist.
+ /// Existing databases are baselined onto instead of being
+ /// re-created: ones with tables but no __EFMigrationsHistory (created by the old schema.sql),
+ /// and ones whose history still lists the pre-squash chain. A database that stopped *mid*-chain
+ /// can no longer be upgraded — the incremental migrations are gone — and throws instead of
+ /// being silently stamped onto a schema it doesn't have.
///
public static void MigrateAndConfigure(ClaudeDoDbContext db)
{
@@ -101,8 +109,6 @@ public class ClaudeDoDbContext : DbContext
fkCmd.ExecuteNonQuery();
}
- // If the 'lists' table exists but __EFMigrationsHistory does not,
- // this is a pre-EF database. Baseline the InitialCreate migration.
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='lists'";
@@ -113,16 +119,42 @@ public class ClaudeDoDbContext : DbContext
if (hasLists && !hasHistory)
{
- cmd.CommandText = """
+ // Pre-EF database: tables, no history at all.
+ cmd.CommandText = $"""
CREATE TABLE "__EFMigrationsHistory" (
"MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY,
"ProductVersion" TEXT NOT NULL
);
INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
- VALUES ('20260416064948_InitialCreate', '8.0.11');
+ VALUES ('{SquashedMigrationId}', '8.0.11');
""";
cmd.ExecuteNonQuery();
}
+ else if (hasLists && hasHistory)
+ {
+ cmd.CommandText = $"""SELECT COUNT(*) FROM "__EFMigrationsHistory" WHERE "MigrationId" = '{SquashedMigrationId}'""";
+ var alreadySquashed = Convert.ToInt64(cmd.ExecuteScalar()) > 0;
+
+ if (!alreadySquashed)
+ {
+ cmd.CommandText = """SELECT MAX("MigrationId") FROM "__EFMigrationsHistory" """;
+ var newest = cmd.ExecuteScalar() as string ?? "";
+
+ if (newest != LastPreSquashMigrationId)
+ throw new InvalidOperationException(
+ $"This database was last migrated by '{newest}', but the migration history was " +
+ $"squashed into '{SquashedMigrationId}' and the incremental migrations no longer " +
+ "exist. Reinstall ClaudeDo against a fresh database (or restore a backup taken " +
+ $"after '{LastPreSquashMigrationId}').");
+
+ cmd.CommandText = $"""
+ DELETE FROM "__EFMigrationsHistory";
+ INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion")
+ VALUES ('{SquashedMigrationId}', '8.0.11');
+ """;
+ cmd.ExecuteNonQuery();
+ }
+ }
}
}
finally
diff --git a/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.Designer.cs b/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.Designer.cs
deleted file mode 100644
index 8474e6f7..00000000
--- a/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.Designer.cs
+++ /dev/null
@@ -1,482 +0,0 @@
-//
-using System;
-using ClaudeDo.Data;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-#nullable disable
-
-namespace ClaudeDo.Data.Migrations
-{
- [DbContext(typeof(ClaudeDoDbContext))]
- [Migration("20260416064948_InitialCreate")]
- partial class InitialCreate
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
- {
- b.Property("ListId")
- .HasColumnType("TEXT")
- .HasColumnName("list_id");
-
- b.Property("AgentPath")
- .HasColumnType("TEXT")
- .HasColumnName("agent_path");
-
- b.Property("Model")
- .HasColumnType("TEXT")
- .HasColumnName("model");
-
- b.Property("SystemPrompt")
- .HasColumnType("TEXT")
- .HasColumnName("system_prompt");
-
- b.HasKey("ListId");
-
- b.ToTable("list_config", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("DefaultCommitType")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("chore")
- .HasColumnName("default_commit_type");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("name");
-
- b.Property("WorkingDir")
- .HasColumnType("TEXT")
- .HasColumnName("working_dir");
-
- b.HasKey("Id");
-
- b.ToTable("lists", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("Completed")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("completed");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("OrderNum")
- .HasColumnType("INTEGER")
- .HasColumnName("order_num");
-
- b.Property("TaskId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("Title")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("title");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId")
- .HasDatabaseName("idx_subtasks_task_id");
-
- b.ToTable("subtasks", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TagEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("name");
-
- b.HasKey("Id");
-
- b.HasIndex("Name")
- .IsUnique();
-
- b.ToTable("tags", (string)null);
-
- b.HasData(
- new
- {
- Id = 1L,
- Name = "agent"
- },
- new
- {
- Id = 2L,
- Name = "manual"
- });
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("AgentPath")
- .HasColumnType("TEXT")
- .HasColumnName("agent_path");
-
- b.Property("CommitType")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("chore")
- .HasColumnName("commit_type");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("Description")
- .HasColumnType("TEXT")
- .HasColumnName("description");
-
- b.Property("FinishedAt")
- .HasColumnType("TEXT")
- .HasColumnName("finished_at");
-
- b.Property("ListId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("list_id");
-
- b.Property("LogPath")
- .HasColumnType("TEXT")
- .HasColumnName("log_path");
-
- b.Property("Model")
- .HasColumnType("TEXT")
- .HasColumnName("model");
-
- b.Property("Result")
- .HasColumnType("TEXT")
- .HasColumnName("result");
-
- b.Property("ScheduledFor")
- .HasColumnType("TEXT")
- .HasColumnName("scheduled_for");
-
- b.Property("StartedAt")
- .HasColumnType("TEXT")
- .HasColumnName("started_at");
-
- b.Property("Status")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("status");
-
- b.Property("SystemPrompt")
- .HasColumnType("TEXT")
- .HasColumnName("system_prompt");
-
- b.Property("Title")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("title");
-
- b.HasKey("Id");
-
- b.HasIndex("ListId")
- .HasDatabaseName("idx_tasks_list_id");
-
- b.HasIndex("Status")
- .HasDatabaseName("idx_tasks_status");
-
- b.ToTable("tasks", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("ErrorMarkdown")
- .HasColumnType("TEXT")
- .HasColumnName("error_markdown");
-
- b.Property("ExitCode")
- .HasColumnType("INTEGER")
- .HasColumnName("exit_code");
-
- b.Property("FinishedAt")
- .HasColumnType("TEXT")
- .HasColumnName("finished_at");
-
- b.Property("IsRetry")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("is_retry");
-
- b.Property("LogPath")
- .HasColumnType("TEXT")
- .HasColumnName("log_path");
-
- b.Property("Prompt")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("prompt");
-
- b.Property("ResultMarkdown")
- .HasColumnType("TEXT")
- .HasColumnName("result_markdown");
-
- b.Property("RunNumber")
- .HasColumnType("INTEGER")
- .HasColumnName("run_number");
-
- b.Property("SessionId")
- .HasColumnType("TEXT")
- .HasColumnName("session_id");
-
- b.Property("StartedAt")
- .HasColumnType("TEXT")
- .HasColumnName("started_at");
-
- b.Property("StructuredOutputJson")
- .HasColumnType("TEXT")
- .HasColumnName("structured_output");
-
- b.Property("TaskId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("TokensIn")
- .HasColumnType("INTEGER")
- .HasColumnName("tokens_in");
-
- b.Property("TokensOut")
- .HasColumnType("INTEGER")
- .HasColumnName("tokens_out");
-
- b.Property("TurnCount")
- .HasColumnType("INTEGER")
- .HasColumnName("turn_count");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId")
- .HasDatabaseName("idx_task_runs_task_id");
-
- b.ToTable("task_runs", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
- {
- b.Property("TaskId")
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("BaseCommit")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("base_commit");
-
- b.Property("BranchName")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("branch_name");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("DiffStat")
- .HasColumnType("TEXT")
- .HasColumnName("diff_stat");
-
- b.Property("HeadCommit")
- .HasColumnType("TEXT")
- .HasColumnName("head_commit");
-
- b.Property("Path")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("path");
-
- b.Property("State")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("active")
- .HasColumnName("state");
-
- b.HasKey("TaskId");
-
- b.ToTable("worktrees", (string)null);
- });
-
- modelBuilder.Entity("list_tags", b =>
- {
- b.Property("list_id")
- .HasColumnType("TEXT");
-
- b.Property("tag_id")
- .HasColumnType("INTEGER");
-
- b.HasKey("list_id", "tag_id");
-
- b.HasIndex("tag_id");
-
- b.ToTable("list_tags", (string)null);
- });
-
- modelBuilder.Entity("task_tags", b =>
- {
- b.Property("task_id")
- .HasColumnType("TEXT");
-
- b.Property("tag_id")
- .HasColumnType("INTEGER");
-
- b.HasKey("task_id", "tag_id");
-
- b.HasIndex("tag_id");
-
- b.ToTable("task_tags", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
- .WithOne("Config")
- .HasForeignKey("ClaudeDo.Data.Models.ListConfigEntity", "ListId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("List");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
- .WithMany("Subtasks")
- .HasForeignKey("TaskId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Task");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
- .WithMany("Tasks")
- .HasForeignKey("ListId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("List");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
- .WithMany("Runs")
- .HasForeignKey("TaskId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Task");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
- .WithOne("Worktree")
- .HasForeignKey("ClaudeDo.Data.Models.WorktreeEntity", "TaskId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Task");
- });
-
- modelBuilder.Entity("list_tags", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.ListEntity", null)
- .WithMany()
- .HasForeignKey("list_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
- .WithMany()
- .HasForeignKey("tag_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("task_tags", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
- .WithMany()
- .HasForeignKey("tag_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
- .WithMany()
- .HasForeignKey("task_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
- {
- b.Navigation("Config");
-
- b.Navigation("Tasks");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
- {
- b.Navigation("Runs");
-
- b.Navigation("Subtasks");
-
- b.Navigation("Worktree");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.cs b/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.cs
deleted file mode 100644
index 301b9316..00000000
--- a/src/ClaudeDo.Data/Migrations/20260416064948_InitialCreate.cs
+++ /dev/null
@@ -1,298 +0,0 @@
-using System;
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
-
-namespace ClaudeDo.Data.Migrations
-{
- ///
- public partial class InitialCreate : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.CreateTable(
- name: "lists",
- columns: table => new
- {
- id = table.Column(type: "TEXT", nullable: false),
- name = table.Column(type: "TEXT", nullable: false),
- created_at = table.Column(type: "TEXT", nullable: false),
- working_dir = table.Column(type: "TEXT", nullable: true),
- default_commit_type = table.Column(type: "TEXT", nullable: false, defaultValue: "chore")
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_lists", x => x.id);
- });
-
- migrationBuilder.CreateTable(
- name: "tags",
- columns: table => new
- {
- id = table.Column(type: "INTEGER", nullable: false)
- .Annotation("Sqlite:Autoincrement", true),
- name = table.Column(type: "TEXT", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_tags", x => x.id);
- });
-
- migrationBuilder.CreateTable(
- name: "list_config",
- columns: table => new
- {
- list_id = table.Column(type: "TEXT", nullable: false),
- model = table.Column(type: "TEXT", nullable: true),
- system_prompt = table.Column(type: "TEXT", nullable: true),
- agent_path = table.Column(type: "TEXT", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_list_config", x => x.list_id);
- table.ForeignKey(
- name: "FK_list_config_lists_list_id",
- column: x => x.list_id,
- principalTable: "lists",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "tasks",
- columns: table => new
- {
- id = table.Column(type: "TEXT", nullable: false),
- list_id = table.Column(type: "TEXT", nullable: false),
- title = table.Column(type: "TEXT", nullable: false),
- description = table.Column(type: "TEXT", nullable: true),
- status = table.Column(type: "TEXT", nullable: false),
- scheduled_for = table.Column(type: "TEXT", nullable: true),
- result = table.Column(type: "TEXT", nullable: true),
- log_path = table.Column(type: "TEXT", nullable: true),
- created_at = table.Column(type: "TEXT", nullable: false),
- started_at = table.Column(type: "TEXT", nullable: true),
- finished_at = table.Column(type: "TEXT", nullable: true),
- commit_type = table.Column(type: "TEXT", nullable: false, defaultValue: "chore"),
- model = table.Column(type: "TEXT", nullable: true),
- system_prompt = table.Column(type: "TEXT", nullable: true),
- agent_path = table.Column(type: "TEXT", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_tasks", x => x.id);
- table.ForeignKey(
- name: "FK_tasks_lists_list_id",
- column: x => x.list_id,
- principalTable: "lists",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "list_tags",
- columns: table => new
- {
- list_id = table.Column(type: "TEXT", nullable: false),
- tag_id = table.Column(type: "INTEGER", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_list_tags", x => new { x.list_id, x.tag_id });
- table.ForeignKey(
- name: "FK_list_tags_lists_list_id",
- column: x => x.list_id,
- principalTable: "lists",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "FK_list_tags_tags_tag_id",
- column: x => x.tag_id,
- principalTable: "tags",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "subtasks",
- columns: table => new
- {
- id = table.Column(type: "TEXT", nullable: false),
- task_id = table.Column(type: "TEXT", nullable: false),
- title = table.Column(type: "TEXT", nullable: false),
- completed = table.Column(type: "INTEGER", nullable: false, defaultValue: false),
- order_num = table.Column(type: "INTEGER", nullable: false),
- created_at = table.Column(type: "TEXT", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_subtasks", x => x.id);
- table.ForeignKey(
- name: "FK_subtasks_tasks_task_id",
- column: x => x.task_id,
- principalTable: "tasks",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "task_runs",
- columns: table => new
- {
- id = table.Column(type: "TEXT", nullable: false),
- task_id = table.Column(type: "TEXT", nullable: false),
- run_number = table.Column(type: "INTEGER", nullable: false),
- session_id = table.Column(type: "TEXT", nullable: true),
- is_retry = table.Column(type: "INTEGER", nullable: false, defaultValue: false),
- prompt = table.Column(type: "TEXT", nullable: false),
- result_markdown = table.Column(type: "TEXT", nullable: true),
- structured_output = table.Column(type: "TEXT", nullable: true),
- error_markdown = table.Column(type: "TEXT", nullable: true),
- exit_code = table.Column(type: "INTEGER", nullable: true),
- turn_count = table.Column(type: "INTEGER", nullable: true),
- tokens_in = table.Column(type: "INTEGER", nullable: true),
- tokens_out = table.Column(type: "INTEGER", nullable: true),
- log_path = table.Column(type: "TEXT", nullable: true),
- started_at = table.Column(type: "TEXT", nullable: true),
- finished_at = table.Column(type: "TEXT", nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_task_runs", x => x.id);
- table.ForeignKey(
- name: "FK_task_runs_tasks_task_id",
- column: x => x.task_id,
- principalTable: "tasks",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "task_tags",
- columns: table => new
- {
- task_id = table.Column(type: "TEXT", nullable: false),
- tag_id = table.Column(type: "INTEGER", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_task_tags", x => new { x.task_id, x.tag_id });
- table.ForeignKey(
- name: "FK_task_tags_tags_tag_id",
- column: x => x.tag_id,
- principalTable: "tags",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- table.ForeignKey(
- name: "FK_task_tags_tasks_task_id",
- column: x => x.task_id,
- principalTable: "tasks",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.CreateTable(
- name: "worktrees",
- columns: table => new
- {
- task_id = table.Column(type: "TEXT", nullable: false),
- path = table.Column(type: "TEXT", nullable: false),
- branch_name = table.Column(type: "TEXT", nullable: false),
- base_commit = table.Column(type: "TEXT", nullable: false),
- head_commit = table.Column(type: "TEXT", nullable: true),
- diff_stat = table.Column(type: "TEXT", nullable: true),
- state = table.Column(type: "TEXT", nullable: false, defaultValue: "active"),
- created_at = table.Column(type: "TEXT", nullable: false)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_worktrees", x => x.task_id);
- table.ForeignKey(
- name: "FK_worktrees_tasks_task_id",
- column: x => x.task_id,
- principalTable: "tasks",
- principalColumn: "id",
- onDelete: ReferentialAction.Cascade);
- });
-
- migrationBuilder.InsertData(
- table: "tags",
- columns: new[] { "id", "name" },
- values: new object[,]
- {
- { 1L, "agent" },
- { 2L, "manual" }
- });
-
- migrationBuilder.CreateIndex(
- name: "IX_list_tags_tag_id",
- table: "list_tags",
- column: "tag_id");
-
- migrationBuilder.CreateIndex(
- name: "idx_subtasks_task_id",
- table: "subtasks",
- column: "task_id");
-
- migrationBuilder.CreateIndex(
- name: "IX_tags_name",
- table: "tags",
- column: "name",
- unique: true);
-
- migrationBuilder.CreateIndex(
- name: "idx_task_runs_task_id",
- table: "task_runs",
- column: "task_id");
-
- migrationBuilder.CreateIndex(
- name: "IX_task_tags_tag_id",
- table: "task_tags",
- column: "tag_id");
-
- migrationBuilder.CreateIndex(
- name: "idx_tasks_list_id",
- table: "tasks",
- column: "list_id");
-
- migrationBuilder.CreateIndex(
- name: "idx_tasks_status",
- table: "tasks",
- column: "status");
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropTable(
- name: "list_config");
-
- migrationBuilder.DropTable(
- name: "list_tags");
-
- migrationBuilder.DropTable(
- name: "subtasks");
-
- migrationBuilder.DropTable(
- name: "task_runs");
-
- migrationBuilder.DropTable(
- name: "task_tags");
-
- migrationBuilder.DropTable(
- name: "worktrees");
-
- migrationBuilder.DropTable(
- name: "tags");
-
- migrationBuilder.DropTable(
- name: "tasks");
-
- migrationBuilder.DropTable(
- name: "lists");
- }
- }
-}
diff --git a/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.Designer.cs b/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.Designer.cs
deleted file mode 100644
index b8fa6b69..00000000
--- a/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.Designer.cs
+++ /dev/null
@@ -1,498 +0,0 @@
-//
-using System;
-using ClaudeDo.Data;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-#nullable disable
-
-namespace ClaudeDo.Data.Migrations
-{
- [DbContext(typeof(ClaudeDoDbContext))]
- [Migration("20260420075929_AddTaskFlagsAndNotes")]
- partial class AddTaskFlagsAndNotes
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
- {
- b.Property("ListId")
- .HasColumnType("TEXT")
- .HasColumnName("list_id");
-
- b.Property("AgentPath")
- .HasColumnType("TEXT")
- .HasColumnName("agent_path");
-
- b.Property("Model")
- .HasColumnType("TEXT")
- .HasColumnName("model");
-
- b.Property("SystemPrompt")
- .HasColumnType("TEXT")
- .HasColumnName("system_prompt");
-
- b.HasKey("ListId");
-
- b.ToTable("list_config", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("DefaultCommitType")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("chore")
- .HasColumnName("default_commit_type");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("name");
-
- b.Property("WorkingDir")
- .HasColumnType("TEXT")
- .HasColumnName("working_dir");
-
- b.HasKey("Id");
-
- b.ToTable("lists", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("Completed")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("completed");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("OrderNum")
- .HasColumnType("INTEGER")
- .HasColumnName("order_num");
-
- b.Property("TaskId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("Title")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("title");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId")
- .HasDatabaseName("idx_subtasks_task_id");
-
- b.ToTable("subtasks", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TagEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("name");
-
- b.HasKey("Id");
-
- b.HasIndex("Name")
- .IsUnique();
-
- b.ToTable("tags", (string)null);
-
- b.HasData(
- new
- {
- Id = 1L,
- Name = "agent"
- },
- new
- {
- Id = 2L,
- Name = "manual"
- });
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("AgentPath")
- .HasColumnType("TEXT")
- .HasColumnName("agent_path");
-
- b.Property("CommitType")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("chore")
- .HasColumnName("commit_type");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("Description")
- .HasColumnType("TEXT")
- .HasColumnName("description");
-
- b.Property("FinishedAt")
- .HasColumnType("TEXT")
- .HasColumnName("finished_at");
-
- b.Property("IsMyDay")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("is_my_day");
-
- b.Property("IsStarred")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("is_starred");
-
- b.Property("ListId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("list_id");
-
- b.Property("LogPath")
- .HasColumnType("TEXT")
- .HasColumnName("log_path");
-
- b.Property("Model")
- .HasColumnType("TEXT")
- .HasColumnName("model");
-
- b.Property("Notes")
- .HasColumnType("TEXT")
- .HasColumnName("notes");
-
- b.Property("Result")
- .HasColumnType("TEXT")
- .HasColumnName("result");
-
- b.Property("ScheduledFor")
- .HasColumnType("TEXT")
- .HasColumnName("scheduled_for");
-
- b.Property("StartedAt")
- .HasColumnType("TEXT")
- .HasColumnName("started_at");
-
- b.Property("Status")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("status");
-
- b.Property("SystemPrompt")
- .HasColumnType("TEXT")
- .HasColumnName("system_prompt");
-
- b.Property("Title")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("title");
-
- b.HasKey("Id");
-
- b.HasIndex("ListId")
- .HasDatabaseName("idx_tasks_list_id");
-
- b.HasIndex("Status")
- .HasDatabaseName("idx_tasks_status");
-
- b.ToTable("tasks", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("ErrorMarkdown")
- .HasColumnType("TEXT")
- .HasColumnName("error_markdown");
-
- b.Property("ExitCode")
- .HasColumnType("INTEGER")
- .HasColumnName("exit_code");
-
- b.Property("FinishedAt")
- .HasColumnType("TEXT")
- .HasColumnName("finished_at");
-
- b.Property("IsRetry")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("is_retry");
-
- b.Property("LogPath")
- .HasColumnType("TEXT")
- .HasColumnName("log_path");
-
- b.Property("Prompt")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("prompt");
-
- b.Property("ResultMarkdown")
- .HasColumnType("TEXT")
- .HasColumnName("result_markdown");
-
- b.Property("RunNumber")
- .HasColumnType("INTEGER")
- .HasColumnName("run_number");
-
- b.Property("SessionId")
- .HasColumnType("TEXT")
- .HasColumnName("session_id");
-
- b.Property("StartedAt")
- .HasColumnType("TEXT")
- .HasColumnName("started_at");
-
- b.Property("StructuredOutputJson")
- .HasColumnType("TEXT")
- .HasColumnName("structured_output");
-
- b.Property("TaskId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("TokensIn")
- .HasColumnType("INTEGER")
- .HasColumnName("tokens_in");
-
- b.Property("TokensOut")
- .HasColumnType("INTEGER")
- .HasColumnName("tokens_out");
-
- b.Property("TurnCount")
- .HasColumnType("INTEGER")
- .HasColumnName("turn_count");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId")
- .HasDatabaseName("idx_task_runs_task_id");
-
- b.ToTable("task_runs", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
- {
- b.Property("TaskId")
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("BaseCommit")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("base_commit");
-
- b.Property("BranchName")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("branch_name");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("DiffStat")
- .HasColumnType("TEXT")
- .HasColumnName("diff_stat");
-
- b.Property("HeadCommit")
- .HasColumnType("TEXT")
- .HasColumnName("head_commit");
-
- b.Property("Path")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("path");
-
- b.Property("State")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("active")
- .HasColumnName("state");
-
- b.HasKey("TaskId");
-
- b.ToTable("worktrees", (string)null);
- });
-
- modelBuilder.Entity("list_tags", b =>
- {
- b.Property("list_id")
- .HasColumnType("TEXT");
-
- b.Property("tag_id")
- .HasColumnType("INTEGER");
-
- b.HasKey("list_id", "tag_id");
-
- b.HasIndex("tag_id");
-
- b.ToTable("list_tags", (string)null);
- });
-
- modelBuilder.Entity("task_tags", b =>
- {
- b.Property("task_id")
- .HasColumnType("TEXT");
-
- b.Property("tag_id")
- .HasColumnType("INTEGER");
-
- b.HasKey("task_id", "tag_id");
-
- b.HasIndex("tag_id");
-
- b.ToTable("task_tags", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
- .WithOne("Config")
- .HasForeignKey("ClaudeDo.Data.Models.ListConfigEntity", "ListId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("List");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
- .WithMany("Subtasks")
- .HasForeignKey("TaskId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Task");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.ListEntity", "List")
- .WithMany("Tasks")
- .HasForeignKey("ListId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("List");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
- .WithMany("Runs")
- .HasForeignKey("TaskId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Task");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", "Task")
- .WithOne("Worktree")
- .HasForeignKey("ClaudeDo.Data.Models.WorktreeEntity", "TaskId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Task");
- });
-
- modelBuilder.Entity("list_tags", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.ListEntity", null)
- .WithMany()
- .HasForeignKey("list_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
- .WithMany()
- .HasForeignKey("tag_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("task_tags", b =>
- {
- b.HasOne("ClaudeDo.Data.Models.TagEntity", null)
- .WithMany()
- .HasForeignKey("tag_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("ClaudeDo.Data.Models.TaskEntity", null)
- .WithMany()
- .HasForeignKey("task_id")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
- {
- b.Navigation("Config");
-
- b.Navigation("Tasks");
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
- {
- b.Navigation("Runs");
-
- b.Navigation("Subtasks");
-
- b.Navigation("Worktree");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.cs b/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.cs
deleted file mode 100644
index 75467678..00000000
--- a/src/ClaudeDo.Data/Migrations/20260420075929_AddTaskFlagsAndNotes.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace ClaudeDo.Data.Migrations
-{
- ///
- public partial class AddTaskFlagsAndNotes : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AddColumn(
- name: "is_my_day",
- table: "tasks",
- type: "INTEGER",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "is_starred",
- table: "tasks",
- type: "INTEGER",
- nullable: false,
- defaultValue: false);
-
- migrationBuilder.AddColumn(
- name: "notes",
- table: "tasks",
- type: "TEXT",
- nullable: true);
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropColumn(
- name: "is_my_day",
- table: "tasks");
-
- migrationBuilder.DropColumn(
- name: "is_starred",
- table: "tasks");
-
- migrationBuilder.DropColumn(
- name: "notes",
- table: "tasks");
- }
- }
-}
diff --git a/src/ClaudeDo.Data/Migrations/20260421113614_AddAppSettings.Designer.cs b/src/ClaudeDo.Data/Migrations/20260421113614_AddAppSettings.Designer.cs
deleted file mode 100644
index a03d20e6..00000000
--- a/src/ClaudeDo.Data/Migrations/20260421113614_AddAppSettings.Designer.cs
+++ /dev/null
@@ -1,572 +0,0 @@
-//
-using System;
-using ClaudeDo.Data;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-#nullable disable
-
-namespace ClaudeDo.Data.Migrations
-{
- [DbContext(typeof(ClaudeDoDbContext))]
- [Migration("20260421113614_AddAppSettings")]
- partial class AddAppSettings
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder.HasAnnotation("ProductVersion", "8.0.11");
-
- modelBuilder.Entity("ClaudeDo.Data.Models.AppSettingsEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property("CentralWorktreeRoot")
- .HasColumnType("TEXT")
- .HasColumnName("central_worktree_root");
-
- b.Property("DefaultClaudeInstructions")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("")
- .HasColumnName("default_claude_instructions");
-
- b.Property("DefaultMaxTurns")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(30)
- .HasColumnName("default_max_turns");
-
- b.Property("DefaultModel")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("sonnet")
- .HasColumnName("default_model");
-
- b.Property("DefaultPermissionMode")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("bypassPermissions")
- .HasColumnName("default_permission_mode");
-
- b.Property("WorktreeAutoCleanupDays")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(7)
- .HasColumnName("worktree_auto_cleanup_days");
-
- b.Property("WorktreeAutoCleanupEnabled")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("worktree_auto_cleanup_enabled");
-
- b.Property("WorktreeStrategy")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("sibling")
- .HasColumnName("worktree_strategy");
-
- b.HasKey("Id");
-
- b.ToTable("app_settings", (string)null);
-
- b.HasData(
- new
- {
- Id = 1,
- DefaultClaudeInstructions = "",
- DefaultMaxTurns = 30,
- DefaultModel = "sonnet",
- DefaultPermissionMode = "bypassPermissions",
- WorktreeAutoCleanupDays = 7,
- WorktreeAutoCleanupEnabled = false,
- WorktreeStrategy = "sibling"
- });
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListConfigEntity", b =>
- {
- b.Property("ListId")
- .HasColumnType("TEXT")
- .HasColumnName("list_id");
-
- b.Property("AgentPath")
- .HasColumnType("TEXT")
- .HasColumnName("agent_path");
-
- b.Property("Model")
- .HasColumnType("TEXT")
- .HasColumnName("model");
-
- b.Property("SystemPrompt")
- .HasColumnType("TEXT")
- .HasColumnName("system_prompt");
-
- b.HasKey("ListId");
-
- b.ToTable("list_config", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.ListEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("DefaultCommitType")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("chore")
- .HasColumnName("default_commit_type");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("name");
-
- b.Property("WorkingDir")
- .HasColumnType("TEXT")
- .HasColumnName("working_dir");
-
- b.HasKey("Id");
-
- b.ToTable("lists", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.SubtaskEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("Completed")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("completed");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("OrderNum")
- .HasColumnType("INTEGER")
- .HasColumnName("order_num");
-
- b.Property("TaskId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("Title")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("title");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId")
- .HasDatabaseName("idx_subtasks_task_id");
-
- b.ToTable("subtasks", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TagEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasColumnName("id");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("name");
-
- b.HasKey("Id");
-
- b.HasIndex("Name")
- .IsUnique();
-
- b.ToTable("tags", (string)null);
-
- b.HasData(
- new
- {
- Id = 1L,
- Name = "agent"
- },
- new
- {
- Id = 2L,
- Name = "manual"
- });
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("AgentPath")
- .HasColumnType("TEXT")
- .HasColumnName("agent_path");
-
- b.Property("CommitType")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("chore")
- .HasColumnName("commit_type");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("Description")
- .HasColumnType("TEXT")
- .HasColumnName("description");
-
- b.Property("FinishedAt")
- .HasColumnType("TEXT")
- .HasColumnName("finished_at");
-
- b.Property("IsMyDay")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("is_my_day");
-
- b.Property("IsStarred")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("is_starred");
-
- b.Property("ListId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("list_id");
-
- b.Property("LogPath")
- .HasColumnType("TEXT")
- .HasColumnName("log_path");
-
- b.Property("Model")
- .HasColumnType("TEXT")
- .HasColumnName("model");
-
- b.Property("Notes")
- .HasColumnType("TEXT")
- .HasColumnName("notes");
-
- b.Property("Result")
- .HasColumnType("TEXT")
- .HasColumnName("result");
-
- b.Property("ScheduledFor")
- .HasColumnType("TEXT")
- .HasColumnName("scheduled_for");
-
- b.Property("StartedAt")
- .HasColumnType("TEXT")
- .HasColumnName("started_at");
-
- b.Property("Status")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("status");
-
- b.Property("SystemPrompt")
- .HasColumnType("TEXT")
- .HasColumnName("system_prompt");
-
- b.Property("Title")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("title");
-
- b.HasKey("Id");
-
- b.HasIndex("ListId")
- .HasDatabaseName("idx_tasks_list_id");
-
- b.HasIndex("Status")
- .HasDatabaseName("idx_tasks_status");
-
- b.ToTable("tasks", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.TaskRunEntity", b =>
- {
- b.Property("Id")
- .HasColumnType("TEXT")
- .HasColumnName("id");
-
- b.Property("ErrorMarkdown")
- .HasColumnType("TEXT")
- .HasColumnName("error_markdown");
-
- b.Property("ExitCode")
- .HasColumnType("INTEGER")
- .HasColumnName("exit_code");
-
- b.Property("FinishedAt")
- .HasColumnType("TEXT")
- .HasColumnName("finished_at");
-
- b.Property("IsRetry")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER")
- .HasDefaultValue(false)
- .HasColumnName("is_retry");
-
- b.Property("LogPath")
- .HasColumnType("TEXT")
- .HasColumnName("log_path");
-
- b.Property("Prompt")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("prompt");
-
- b.Property("ResultMarkdown")
- .HasColumnType("TEXT")
- .HasColumnName("result_markdown");
-
- b.Property("RunNumber")
- .HasColumnType("INTEGER")
- .HasColumnName("run_number");
-
- b.Property("SessionId")
- .HasColumnType("TEXT")
- .HasColumnName("session_id");
-
- b.Property("StartedAt")
- .HasColumnType("TEXT")
- .HasColumnName("started_at");
-
- b.Property("StructuredOutputJson")
- .HasColumnType("TEXT")
- .HasColumnName("structured_output");
-
- b.Property("TaskId")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("TokensIn")
- .HasColumnType("INTEGER")
- .HasColumnName("tokens_in");
-
- b.Property("TokensOut")
- .HasColumnType("INTEGER")
- .HasColumnName("tokens_out");
-
- b.Property("TurnCount")
- .HasColumnType("INTEGER")
- .HasColumnName("turn_count");
-
- b.HasKey("Id");
-
- b.HasIndex("TaskId")
- .HasDatabaseName("idx_task_runs_task_id");
-
- b.ToTable("task_runs", (string)null);
- });
-
- modelBuilder.Entity("ClaudeDo.Data.Models.WorktreeEntity", b =>
- {
- b.Property("TaskId")
- .HasColumnType("TEXT")
- .HasColumnName("task_id");
-
- b.Property("BaseCommit")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("base_commit");
-
- b.Property("BranchName")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("branch_name");
-
- b.Property("CreatedAt")
- .HasColumnType("TEXT")
- .HasColumnName("created_at");
-
- b.Property("DiffStat")
- .HasColumnType("TEXT")
- .HasColumnName("diff_stat");
-
- b.Property("HeadCommit")
- .HasColumnType("TEXT")
- .HasColumnName("head_commit");
-
- b.Property("Path")
- .IsRequired()
- .HasColumnType("TEXT")
- .HasColumnName("path");
-
- b.Property("State")
- .IsRequired()
- .ValueGeneratedOnAdd()
- .HasColumnType("TEXT")
- .HasDefaultValue("active")
- .HasColumnName("state");
-
- b.HasKey("TaskId");
-
- b.ToTable("worktrees", (string)null);
- });
-
- modelBuilder.Entity("list_tags", b =>
- {
- b.Property