Files
ClaudeDo/src/ClaudeDo.Data/Migrations/20260826094154_InitialCreate.cs
T
mika kuns 39d8241360 refactor(data): squash the 40 migrations into one InitialCreate
The incremental chain was ~31k lines of generated Designer snapshots for a
schema no shipped database steps through anymore. MigrateAndConfigure now
baselines an existing DB onto the squashed id (pre-EF, or history ending at
AddPrimeActionKind) and throws with a reinstall message for a mid-chain DB.
MigrationBaselineTests covers all three paths with a real Migrate().
2026-08-26 13:55:30 +02:00

450 lines
24 KiB
C#

using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace ClaudeDo.Data.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "app_settings",
columns: table => new
{
id = table.Column<int>(type: "INTEGER", nullable: false),
next_task_number = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 1),
default_claude_instructions = table.Column<string>(type: "TEXT", nullable: false, defaultValue: ""),
default_model = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "sonnet"),
default_max_turns = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 40),
default_permission_mode = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "bypassPermissions"),
max_turns_ceiling = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 80),
max_parallel_executions = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 1),
worktree_strategy = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "sibling"),
central_worktree_root = table.Column<string>(type: "TEXT", nullable: true),
worktree_auto_cleanup_enabled = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
worktree_auto_cleanup_days = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 7),
repo_import_folders = table.Column<string>(type: "TEXT", nullable: true),
report_excluded_paths = table.Column<string>(type: "TEXT", nullable: true),
standup_weekday = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 3),
daily_prep_max_tasks = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 5),
session_skills = table.Column<string>(type: "TEXT", nullable: true),
model_presets = table.Column<string>(type: "TEXT", nullable: true),
usage_gate_five_hour_pct = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 80),
usage_gate_seven_day_pct = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 90),
usage_throttle_five_hour_soft_pct = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 50),
usage_throttle_five_hour_hard_pct = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 65),
usage_throttle_seven_day_soft_pct = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 50),
usage_throttle_seven_day_hard_pct = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 65),
auto_continue_on_usage_limit = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false)
},
constraints: table =>
{
table.PrimaryKey("PK_app_settings", x => x.id);
});
migrationBuilder.CreateTable(
name: "daily_notes",
columns: table => new
{
id = table.Column<string>(type: "TEXT", nullable: false),
note_date = table.Column<DateOnly>(type: "TEXT", nullable: false),
text = table.Column<string>(type: "TEXT", nullable: false),
sort_order = table.Column<int>(type: "INTEGER", nullable: false),
created_at = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_daily_notes", x => x.id);
});
migrationBuilder.CreateTable(
name: "lists",
columns: table => new
{
id = table.Column<string>(type: "TEXT", nullable: false),
name = table.Column<string>(type: "TEXT", nullable: false),
created_at = table.Column<DateTime>(type: "TEXT", nullable: false),
working_dir = table.Column<string>(type: "TEXT", nullable: true),
default_commit_type = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "chore"),
sort_order = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 0),
is_manual = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
findings_tracked = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false)
},
constraints: table =>
{
table.PrimaryKey("PK_lists", x => x.id);
});
migrationBuilder.CreateTable(
name: "prime_schedules",
columns: table => new
{
id = table.Column<Guid>(type: "TEXT", nullable: false),
days_of_week = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 31),
action_kind = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "ping"),
time_of_day = table.Column<TimeSpan>(type: "TEXT", nullable: false),
enabled = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: true),
last_run_at = table.Column<DateTimeOffset>(type: "TEXT", nullable: true),
prompt_override = table.Column<string>(type: "TEXT", nullable: true),
created_at = table.Column<DateTimeOffset>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_prime_schedules", x => x.id);
});
migrationBuilder.CreateTable(
name: "session_skills",
columns: table => new
{
name = table.Column<string>(type: "TEXT", nullable: false),
source_url = table.Column<string>(type: "TEXT", nullable: false),
pinned_ref = table.Column<string>(type: "TEXT", nullable: false),
subpath = table.Column<string>(type: "TEXT", nullable: false),
description = table.Column<string>(type: "TEXT", nullable: false),
added_at = table.Column<DateTimeOffset>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_session_skills", x => x.name);
});
migrationBuilder.CreateTable(
name: "week_reports",
columns: table => new
{
id = table.Column<string>(type: "TEXT", nullable: false),
start_date = table.Column<DateOnly>(type: "TEXT", nullable: false),
end_date = table.Column<DateOnly>(type: "TEXT", nullable: false),
markdown = table.Column<string>(type: "TEXT", nullable: false),
generated_at = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_week_reports", x => x.id);
});
migrationBuilder.CreateTable(
name: "list_config",
columns: table => new
{
list_id = table.Column<string>(type: "TEXT", nullable: false),
model = table.Column<string>(type: "TEXT", nullable: true),
system_prompt = table.Column<string>(type: "TEXT", nullable: true),
agent_path = table.Column<string>(type: "TEXT", nullable: true),
max_turns = table.Column<int>(type: "INTEGER", nullable: true),
session_skills = table.Column<string>(type: "TEXT", nullable: true),
verify_command = table.Column<string>(type: "TEXT", nullable: true),
serialize_on_file_overlap = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false)
},
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<string>(type: "TEXT", nullable: false),
number = table.Column<int>(type: "INTEGER", nullable: false),
list_id = table.Column<string>(type: "TEXT", nullable: false),
title = table.Column<string>(type: "TEXT", nullable: false),
description = table.Column<string>(type: "TEXT", nullable: true),
status = table.Column<string>(type: "TEXT", nullable: false),
planning_phase = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "none"),
blocked_by_task_id = table.Column<string>(type: "TEXT", nullable: true),
depends_on_task_id = table.Column<string>(type: "TEXT", nullable: true),
scheduled_for = table.Column<DateTime>(type: "TEXT", nullable: true),
result = table.Column<string>(type: "TEXT", nullable: true),
review_feedback = table.Column<string>(type: "TEXT", nullable: true),
roadblock_count = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 0),
failure_reason = table.Column<string>(type: "TEXT", nullable: true),
failure_turns_used = table.Column<int>(type: "INTEGER", nullable: true),
failure_max_turns = table.Column<int>(type: "INTEGER", nullable: true),
usage_limit_auto_continued_at = table.Column<DateTime>(type: "TEXT", nullable: true),
log_path = table.Column<string>(type: "TEXT", nullable: true),
created_at = table.Column<DateTime>(type: "TEXT", nullable: false),
started_at = table.Column<DateTime>(type: "TEXT", nullable: true),
finished_at = table.Column<DateTime>(type: "TEXT", nullable: true),
commit_type = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "chore"),
model = table.Column<string>(type: "TEXT", nullable: true),
system_prompt = table.Column<string>(type: "TEXT", nullable: true),
agent_path = table.Column<string>(type: "TEXT", nullable: true),
max_turns = table.Column<int>(type: "INTEGER", nullable: true),
is_starred = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
is_my_day = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
is_manual = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
notes = table.Column<string>(type: "TEXT", nullable: true),
sort_order = table.Column<int>(type: "INTEGER", nullable: false, defaultValue: 0),
session_skills = table.Column<string>(type: "TEXT", nullable: true),
scope_globs = table.Column<string>(type: "TEXT", nullable: true),
handler_base_commit = table.Column<string>(type: "TEXT", nullable: true),
handler_head_commit = table.Column<string>(type: "TEXT", nullable: true),
interactive_session_id = table.Column<string>(type: "TEXT", nullable: true),
parent_task_id = table.Column<string>(type: "TEXT", nullable: true),
planning_session_id = table.Column<string>(type: "TEXT", nullable: true),
planning_session_token = table.Column<string>(type: "TEXT", nullable: true),
planning_finalized_at = table.Column<DateTime>(type: "TEXT", nullable: true),
created_by = table.Column<string>(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);
table.ForeignKey(
name: "FK_tasks_tasks_blocked_by_task_id",
column: x => x.blocked_by_task_id,
principalTable: "tasks",
principalColumn: "id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_tasks_tasks_depends_on_task_id",
column: x => x.depends_on_task_id,
principalTable: "tasks",
principalColumn: "id",
onDelete: ReferentialAction.SetNull);
table.ForeignKey(
name: "FK_tasks_tasks_parent_task_id",
column: x => x.parent_task_id,
principalTable: "tasks",
principalColumn: "id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "subtasks",
columns: table => new
{
id = table.Column<string>(type: "TEXT", nullable: false),
task_id = table.Column<string>(type: "TEXT", nullable: false),
title = table.Column<string>(type: "TEXT", nullable: false),
completed = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
order_num = table.Column<int>(type: "INTEGER", nullable: false),
created_at = table.Column<DateTime>(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_attachments",
columns: table => new
{
id = table.Column<string>(type: "TEXT", nullable: false),
task_id = table.Column<string>(type: "TEXT", nullable: false),
file_name = table.Column<string>(type: "TEXT", nullable: false),
byte_size = table.Column<long>(type: "INTEGER", nullable: false),
created_at = table.Column<DateTime>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_task_attachments", x => x.id);
table.ForeignKey(
name: "FK_task_attachments_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<string>(type: "TEXT", nullable: false),
task_id = table.Column<string>(type: "TEXT", nullable: false),
run_number = table.Column<int>(type: "INTEGER", nullable: false),
session_id = table.Column<string>(type: "TEXT", nullable: true),
is_retry = table.Column<bool>(type: "INTEGER", nullable: false, defaultValue: false),
prompt = table.Column<string>(type: "TEXT", nullable: false),
result_markdown = table.Column<string>(type: "TEXT", nullable: true),
structured_output = table.Column<string>(type: "TEXT", nullable: true),
error_markdown = table.Column<string>(type: "TEXT", nullable: true),
exit_code = table.Column<int>(type: "INTEGER", nullable: true),
turn_count = table.Column<int>(type: "INTEGER", nullable: true),
tokens_in = table.Column<int>(type: "INTEGER", nullable: true),
tokens_out = table.Column<int>(type: "INTEGER", nullable: true),
cache_read_tokens = table.Column<int>(type: "INTEGER", nullable: true),
cache_write_tokens = table.Column<int>(type: "INTEGER", nullable: true),
log_path = table.Column<string>(type: "TEXT", nullable: true),
started_at = table.Column<DateTime>(type: "TEXT", nullable: true),
finished_at = table.Column<DateTime>(type: "TEXT", nullable: true),
model = table.Column<string>(type: "TEXT", nullable: true),
result_subtype = table.Column<string>(type: "TEXT", nullable: true),
terminal_reason = table.Column<string>(type: "TEXT", nullable: true),
errors = table.Column<string>(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: "worktrees",
columns: table => new
{
task_id = table.Column<string>(type: "TEXT", nullable: false),
path = table.Column<string>(type: "TEXT", nullable: false),
branch_name = table.Column<string>(type: "TEXT", nullable: false),
base_commit = table.Column<string>(type: "TEXT", nullable: false),
head_commit = table.Column<string>(type: "TEXT", nullable: true),
diff_stat = table.Column<string>(type: "TEXT", nullable: true),
merge_commit = table.Column<string>(type: "TEXT", nullable: true),
state = table.Column<string>(type: "TEXT", nullable: false, defaultValue: "active"),
created_at = table.Column<DateTime>(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: "app_settings",
columns: new[] { "id", "central_worktree_root", "daily_prep_max_tasks", "default_claude_instructions", "default_max_turns", "default_model", "default_permission_mode", "max_parallel_executions", "max_turns_ceiling", "model_presets", "next_task_number", "repo_import_folders", "report_excluded_paths", "session_skills", "standup_weekday", "usage_gate_five_hour_pct", "usage_gate_seven_day_pct", "usage_throttle_five_hour_hard_pct", "usage_throttle_five_hour_soft_pct", "usage_throttle_seven_day_hard_pct", "usage_throttle_seven_day_soft_pct", "worktree_auto_cleanup_days", "worktree_strategy" },
values: new object[] { 1, null, 5, "", 40, "sonnet", "auto", 1, 80, null, 1, null, null, null, 3, 80, 90, 65, 50, 65, 50, 7, "sibling" });
migrationBuilder.CreateIndex(
name: "IX_daily_notes_note_date",
table: "daily_notes",
column: "note_date");
migrationBuilder.CreateIndex(
name: "idx_lists_sort",
table: "lists",
column: "sort_order");
migrationBuilder.CreateIndex(
name: "idx_subtasks_task_id",
table: "subtasks",
column: "task_id");
migrationBuilder.CreateIndex(
name: "idx_task_attachments_task_id",
table: "task_attachments",
column: "task_id");
migrationBuilder.CreateIndex(
name: "idx_task_runs_task_id",
table: "task_runs",
column: "task_id");
migrationBuilder.CreateIndex(
name: "idx_tasks_blocked_by",
table: "tasks",
column: "blocked_by_task_id");
migrationBuilder.CreateIndex(
name: "idx_tasks_depends_on",
table: "tasks",
column: "depends_on_task_id");
migrationBuilder.CreateIndex(
name: "idx_tasks_list_id",
table: "tasks",
column: "list_id");
migrationBuilder.CreateIndex(
name: "idx_tasks_list_sort",
table: "tasks",
columns: new[] { "list_id", "sort_order" });
migrationBuilder.CreateIndex(
name: "idx_tasks_number",
table: "tasks",
column: "number",
unique: true);
migrationBuilder.CreateIndex(
name: "idx_tasks_parent_task_id",
table: "tasks",
column: "parent_task_id");
migrationBuilder.CreateIndex(
name: "idx_tasks_status",
table: "tasks",
column: "status");
migrationBuilder.CreateIndex(
name: "IX_week_reports_start_date_end_date",
table: "week_reports",
columns: new[] { "start_date", "end_date" },
unique: true);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "app_settings");
migrationBuilder.DropTable(
name: "daily_notes");
migrationBuilder.DropTable(
name: "list_config");
migrationBuilder.DropTable(
name: "prime_schedules");
migrationBuilder.DropTable(
name: "session_skills");
migrationBuilder.DropTable(
name: "subtasks");
migrationBuilder.DropTable(
name: "task_attachments");
migrationBuilder.DropTable(
name: "task_runs");
migrationBuilder.DropTable(
name: "week_reports");
migrationBuilder.DropTable(
name: "worktrees");
migrationBuilder.DropTable(
name: "tasks");
migrationBuilder.DropTable(
name: "lists");
}
}
}