This commit is contained in:
Louis Knight-Webb
2025-06-17 19:43:11 -04:00
parent a351110f1b
commit 7f7b6fbc70
34 changed files with 330 additions and 331 deletions

View File

@@ -73,3 +73,5 @@ Try to build the Typescript project after any frontend changes `npm run build`
SQLX queries should be located in backend/src/models/\*
Use getters and setters instead of raw SQL queries where possible.
DATABASE_URL=sqlite:/Users/louisknight-webb/Documents/mission-control.sqlite

View File

@@ -1,12 +1,12 @@
{
"db_name": "SQLite",
"query": "SELECT id, name, git_repo_path, created_at, updated_at FROM projects WHERE git_repo_path = $1",
"query": "SELECT id as \"id!: Uuid\", name, git_repo_path, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\" FROM projects WHERE id = $1",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "name",
@@ -19,12 +19,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
@@ -40,5 +40,5 @@
false
]
},
"hash": "2b1e71e53fbf99fef22324cda3c9c6d5c470dee4d117521362d68678f655863d"
"hash": "0133ba2ace195776eaa714981cdf492d2eaa3dc97dc3379b549a3c4fb8309975"
}

View File

@@ -1,12 +1,12 @@
{
"db_name": "SQLite",
"query": "SELECT id, name, git_repo_path, created_at, updated_at FROM projects ORDER BY created_at DESC",
"query": "SELECT id as \"id!: Uuid\", name, git_repo_path, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\" FROM projects ORDER BY created_at DESC",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "name",
@@ -19,12 +19,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
@@ -40,5 +40,5 @@
false
]
},
"hash": "0bdcd1ef7dad9ce28357ca36ab38cde77bb3e3c8cae51da14eefd08de76e96c1"
"hash": "022ee13a4082ece0cec1100f5c8c4dc5ecbf84018e1c6b735891ec4057e99f72"
}

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "UPDATE task_attempts SET merge_commit = $1, updated_at = datetime('now') WHERE id = $2",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "03f2b02ba6dc5ea2b3cf6b1004caea0ad6bcc10ebd63f441d321a389f026e263"
}

View File

@@ -0,0 +1,62 @@
{
"db_name": "SQLite",
"query": "SELECT \n t.id as \"id!: Uuid\", \n t.project_id as \"project_id!: Uuid\", \n t.title, \n t.description, \n t.status as \"status!: TaskStatus\", \n t.created_at as \"created_at!: DateTime<Utc>\", \n t.updated_at as \"updated_at!: DateTime<Utc>\",\n CASE WHEN in_progress_attempts.task_id IS NOT NULL THEN true ELSE false END as \"has_in_progress_attempt!\"\n FROM tasks t\n LEFT JOIN (\n SELECT DISTINCT ta.task_id \n FROM task_attempts ta\n INNER JOIN (\n SELECT task_attempt_id, MAX(created_at) as latest_created_at\n FROM task_attempt_activities\n GROUP BY task_attempt_id\n ) latest_activity ON ta.id = latest_activity.task_attempt_id\n INNER JOIN task_attempt_activities taa ON ta.id = taa.task_attempt_id \n AND taa.created_at = latest_activity.latest_created_at\n WHERE taa.status = 'inprogress'\n ) in_progress_attempts ON t.id = in_progress_attempts.task_id\n WHERE t.project_id = $1 \n ORDER BY t.created_at DESC",
"describe": {
"columns": [
{
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Blob"
},
{
"name": "project_id!: Uuid",
"ordinal": 1,
"type_info": "Blob"
},
{
"name": "title",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "description",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "status!: TaskStatus",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "created_at!: DateTime<Utc>",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "updated_at!: DateTime<Utc>",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "has_in_progress_attempt!",
"ordinal": 7,
"type_info": "Int"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true,
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "0ac126dc834dc72fd7cbf4cc32ab23fec591cd48114905fadc59d15c38c9718c"
}

View File

@@ -1,20 +0,0 @@
{
"db_name": "SQLite",
"query": "SELECT id FROM projects WHERE id = $1",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true
]
},
"hash": "0f797f257a16320fc6b5b7bb0ad6a859b85395d3cd1872c0ca071c81ade6e3fe"
}

View File

@@ -1,12 +1,12 @@
{
"db_name": "SQLite",
"query": "SELECT id, name, git_repo_path, created_at, updated_at FROM projects WHERE git_repo_path = $1 AND id != $2",
"query": "SELECT id as \"id!: Uuid\", name, git_repo_path, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\" FROM projects WHERE git_repo_path = $1 AND id != $2",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "name",
@@ -19,12 +19,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
@@ -40,5 +40,5 @@
false
]
},
"hash": "b9345914c95a6c014776cf0cbb23dc6c34baaed0ac31f92283c612556727de9b"
"hash": "18bfb3eb9408e5268bccf7a17fe02424df8ae3130b70aaad64c5342c198011c9"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "SELECT id, task_id, worktree_path, base_commit, merge_commit, executor, stdout, stderr, created_at, updated_at \n FROM task_attempts \n WHERE id = $1",
"query": "SELECT id as \"id!: Uuid\", task_id as \"task_id!: Uuid\", worktree_path, base_commit, merge_commit, executor, stdout, stderr, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"\n FROM task_attempts \n WHERE task_id = $1 \n ORDER BY created_at DESC",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "task_id",
"name": "task_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "worktree_path",
@@ -44,12 +44,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 9,
"type_info": "Text"
}
@@ -70,5 +70,5 @@
false
]
},
"hash": "daf039c3aa78ebae2a9a309f46a30442b14082f48b1634c27eaf8bf6d66b4802"
"hash": "1b24e3eeb2782cdb4e5b98a1b82eeba8eb9b51a5b09dde436da6800d29277b1c"
}

View File

@@ -0,0 +1,44 @@
{
"db_name": "SQLite",
"query": "SELECT id as \"id!: Uuid\", task_attempt_id as \"task_attempt_id!: Uuid\", status as \"status!: TaskAttemptStatus\", note, created_at as \"created_at!: DateTime<Utc>\"\n FROM task_attempt_activities \n WHERE task_attempt_id = $1 \n ORDER BY created_at DESC",
"describe": {
"columns": [
{
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Blob"
},
{
"name": "task_attempt_id!: Uuid",
"ordinal": 1,
"type_info": "Blob"
},
{
"name": "status!: TaskAttemptStatus",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "note",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "created_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true,
false,
false,
true,
false
]
},
"hash": "2b317dcc5541a2b778f7c280e7e16976aa603741eda05d663c713e6f91bb5cd6"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "SELECT id, project_id, title, description, status as \"status!: TaskStatus\", created_at, updated_at \n FROM tasks \n WHERE project_id = $1 \n ORDER BY created_at DESC",
"query": "SELECT id as \"id!: Uuid\", project_id as \"project_id!: Uuid\", title, description, status as \"status!: TaskStatus\", created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"\n FROM tasks \n WHERE project_id = $1 \n ORDER BY created_at DESC",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "project_id",
"name": "project_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "title",
@@ -29,12 +29,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 6,
"type_info": "Text"
}
@@ -52,5 +52,5 @@
false
]
},
"hash": "b7dcce1a1dca74bdebca528fbd03cd26293430587af27798c3297d95e06c99af"
"hash": "2c1e9b7c0038a44d9b78791538529107aeaa6bd49501316b67dceb908df873a1"
}

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "UPDATE task_attempts SET stdout = COALESCE(stdout, '') || $1, updated_at = datetime('now') WHERE id = $2",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "3380f443d21ac408f96b014830322bd3411296b9ee8d29fe5f18974221bb0035"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "UPDATE tasks \n SET title = $3, description = $4, status = $5 \n WHERE id = $1 AND project_id = $2 \n RETURNING id, project_id, title, description, status as \"status!: TaskStatus\", created_at, updated_at",
"query": "UPDATE tasks \n SET title = $3, description = $4, status = $5 \n WHERE id = $1 AND project_id = $2 \n RETURNING id as \"id!: Uuid\", project_id as \"project_id!: Uuid\", title, description, status as \"status!: TaskStatus\", created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "project_id",
"name": "project_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "title",
@@ -29,12 +29,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 6,
"type_info": "Text"
}
@@ -52,5 +52,5 @@
false
]
},
"hash": "ce7a3bd6c160c3eda73600590737c2082f9d772adefc5b32c784a337f4b49065"
"hash": "36241e9163a8c496f8e6a662bd50cdfe38a57757432de65d75bf6a10ea134530"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "SELECT ta.id, ta.task_id, ta.worktree_path, ta.base_commit, ta.merge_commit, ta.executor, ta.stdout, ta.stderr, ta.created_at, ta.updated_at \n FROM task_attempts ta \n JOIN tasks t ON ta.task_id = t.id \n WHERE ta.id = $1 AND t.id = $2 AND t.project_id = $3",
"query": "SELECT ta.id as \"id!: Uuid\", ta.task_id as \"task_id!: Uuid\", ta.worktree_path, ta.base_commit, ta.merge_commit, ta.executor, ta.stdout, ta.stderr, ta.created_at as \"created_at!: DateTime<Utc>\", ta.updated_at as \"updated_at!: DateTime<Utc>\"\n FROM task_attempts ta \n JOIN tasks t ON ta.task_id = t.id \n WHERE ta.id = $1 AND t.id = $2 AND t.project_id = $3",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "task_id",
"name": "task_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "worktree_path",
@@ -44,12 +44,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 9,
"type_info": "Text"
}
@@ -70,5 +70,5 @@
false
]
},
"hash": "741d599c2c88d1bc11958f59be4fb53c0ec4006aac9a08c64a4008b249f642bb"
"hash": "3c39fa95b7cf269831467950e5f873f8e0b93bf512a226ccf4d22d2252d80f1b"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "INSERT INTO task_attempt_activities (id, task_attempt_id, status, note) \n VALUES ($1, $2, $3, $4) \n RETURNING id, task_attempt_id, status as \"status!: TaskAttemptStatus\", note, created_at",
"query": "INSERT INTO task_attempt_activities (id, task_attempt_id, status, note) \n VALUES ($1, $2, $3, $4) \n RETURNING id as \"id!: Uuid\", task_attempt_id as \"task_attempt_id!: Uuid\", status as \"status!: TaskAttemptStatus\", note, created_at as \"created_at!: DateTime<Utc>\"",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "task_attempt_id",
"name": "task_attempt_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "status!: TaskAttemptStatus",
@@ -24,7 +24,7 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
@@ -40,5 +40,5 @@
false
]
},
"hash": "d2574d14252ead485e5db4e0eb84afa2fa3e12422f4e6ef6d623b768316e5ef4"
"hash": "57c2623fb47580045d2d3e89133b4f67fef8100a177b80a99045900262b7fd86"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "SELECT id, project_id, title, description, status as \"status!: TaskStatus\", created_at, updated_at \n FROM tasks \n WHERE id = $1 AND project_id = $2",
"query": "SELECT id as \"id!: Uuid\", project_id as \"project_id!: Uuid\", title, description, status as \"status!: TaskStatus\", created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"\n FROM tasks \n WHERE id = $1 AND project_id = $2",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "project_id",
"name": "project_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "title",
@@ -29,12 +29,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 6,
"type_info": "Text"
}
@@ -52,5 +52,5 @@
false
]
},
"hash": "f4d24cec6142ffb70bf1008235921035d310c452da78128420c93707485c0d7f"
"hash": "73a58d62b2f18489ef5be9f4760f3bee51d6dedd550c3be9bf72e29b2203e63c"
}

View File

@@ -1,62 +0,0 @@
{
"db_name": "SQLite",
"query": "SELECT \n t.id, \n t.project_id, \n t.title, \n t.description, \n t.status as \"status!: TaskStatus\", \n t.created_at, \n t.updated_at,\n CASE WHEN in_progress_attempts.task_id IS NOT NULL THEN true ELSE false END as \"has_in_progress_attempt!\"\n FROM tasks t\n LEFT JOIN (\n SELECT DISTINCT ta.task_id \n FROM task_attempts ta\n INNER JOIN (\n SELECT task_attempt_id, MAX(created_at) as latest_created_at\n FROM task_attempt_activities\n GROUP BY task_attempt_id\n ) latest_activity ON ta.id = latest_activity.task_attempt_id\n INNER JOIN task_attempt_activities taa ON ta.id = taa.task_attempt_id \n AND taa.created_at = latest_activity.latest_created_at\n WHERE taa.status = 'inprogress'\n ) in_progress_attempts ON t.id = in_progress_attempts.task_id\n WHERE t.project_id = $1 \n ORDER BY t.created_at DESC",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "project_id",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "title",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "description",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "status!: TaskStatus",
"ordinal": 4,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "updated_at",
"ordinal": 6,
"type_info": "Text"
},
{
"name": "has_in_progress_attempt!",
"ordinal": 7,
"type_info": "Int"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true,
false,
false,
true,
false,
false,
false,
false
]
},
"hash": "8449fdb087cce369ac3aaea98cfd676530014b848304d6dcfc705990c71178d5"
}

View File

@@ -6,7 +6,7 @@
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
}
],
"parameters": {

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "UPDATE task_attempts SET stderr = COALESCE(stderr, '') || $1, updated_at = datetime('now') WHERE id = $2",
"describe": {
"columns": [],
"parameters": {
"Right": 2
},
"nullable": []
},
"hash": "96957aa26773ee77bba123ebe27c675aa7698c235029ba09f2d503fea746baf6"
}

View File

@@ -1,12 +1,12 @@
{
"db_name": "SQLite",
"query": "SELECT id, name, git_repo_path, created_at, updated_at FROM projects WHERE id = $1",
"query": "SELECT id as \"id!: Uuid\", name, git_repo_path, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\" FROM projects WHERE git_repo_path = $1",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "name",
@@ -19,12 +19,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
@@ -40,5 +40,5 @@
false
]
},
"hash": "2658c9a9ac96f7364811d12854256068971bd33f12f8654445969f84a204a5fa"
"hash": "96aade8205a632c862e4dd11118b7b303cbe521c6a42f5a43eda3cf5f8e6ab2c"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "INSERT INTO tasks (id, project_id, title, description, status) \n VALUES ($1, $2, $3, $4, $5) \n RETURNING id, project_id, title, description, status as \"status!: TaskStatus\", created_at, updated_at",
"query": "INSERT INTO tasks (id, project_id, title, description, status) \n VALUES ($1, $2, $3, $4, $5) \n RETURNING id as \"id!: Uuid\", project_id as \"project_id!: Uuid\", title, description, status as \"status!: TaskStatus\", created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "project_id",
"name": "project_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "title",
@@ -29,12 +29,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 6,
"type_info": "Text"
}
@@ -52,5 +52,5 @@
false
]
},
"hash": "c395009379487778ea43d0bdef7bd9d28f4755bcefb775ca036523aa88a4a3d8"
"hash": "9a893c35e2d5fa480396d5f403c3e9263217904dc3dfe43beca9c9541c4be619"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "SELECT id, task_id, worktree_path, base_commit, merge_commit, executor, stdout, stderr, created_at, updated_at \n FROM task_attempts \n WHERE task_id = $1 \n ORDER BY created_at DESC",
"query": "SELECT id as \"id!: Uuid\", task_id as \"task_id!: Uuid\", worktree_path, base_commit, merge_commit, executor, stdout, stderr, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"\n FROM task_attempts \n WHERE id = $1",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "task_id",
"name": "task_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "worktree_path",
@@ -44,12 +44,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 9,
"type_info": "Text"
}
@@ -70,5 +70,5 @@
false
]
},
"hash": "9a9f29419f50995c3d1be237e0e42a04e1a3478aa6919f13882943eb9bc2cfa3"
"hash": "a58a2bdcf1545b9a854e799a2fbb0ddd843886ecbfb8ff15b82fb4bb6c382e4d"
}

View File

@@ -0,0 +1,12 @@
{
"db_name": "SQLite",
"query": "UPDATE task_attempts SET stdout = $1, stderr = $2, updated_at = datetime('now') WHERE id = $3",
"describe": {
"columns": [],
"parameters": {
"Right": 3
},
"nullable": []
},
"hash": "aa7c3034f96c9b2dfd7c1121b9eb7749987b035d603480a8bf15f776d83a0363"
}

View File

@@ -1,12 +1,12 @@
{
"db_name": "SQLite",
"query": "INSERT INTO projects (id, name, git_repo_path) VALUES ($1, $2, $3) RETURNING id, name, git_repo_path, created_at, updated_at",
"query": "INSERT INTO projects (id, name, git_repo_path) VALUES ($1, $2, $3) RETURNING id as \"id!: Uuid\", name, git_repo_path, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "name",
@@ -19,12 +19,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
@@ -40,5 +40,5 @@
false
]
},
"hash": "610b73abcc696879e1d402f8f94b23c3889eebd4fbeeacbc174bf43317ba83c7"
"hash": "ab7c095d6ccb8bb41d159aa7dd4f7feb97505e31427c124b4219a6903e971f5a"
}

View File

@@ -0,0 +1,20 @@
{
"db_name": "SQLite",
"query": "SELECT COUNT(*) as count FROM projects WHERE id = $1",
"describe": {
"columns": [
{
"name": "count",
"ordinal": 0,
"type_info": "Int"
}
],
"parameters": {
"Right": 1
},
"nullable": [
false
]
},
"hash": "b4efb71365b75edd3dfc843f774f7cdb06dc756328ed5929d6b13ef3a956be0e"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "INSERT INTO task_attempts (id, task_id, worktree_path, base_commit, merge_commit, executor, stdout, stderr) \n VALUES ($1, $2, $3, $4, $5, $6, $7, $8) \n RETURNING id, task_id, worktree_path, base_commit, merge_commit, executor, stdout, stderr, created_at, updated_at",
"query": "INSERT INTO task_attempts (id, task_id, worktree_path, base_commit, merge_commit, executor, stdout, stderr) \n VALUES ($1, $2, $3, $4, $5, $6, $7, $8) \n RETURNING id as \"id!: Uuid\", task_id as \"task_id!: Uuid\", worktree_path, base_commit, merge_commit, executor, stdout, stderr, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "task_id",
"name": "task_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "worktree_path",
@@ -44,12 +44,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 8,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 9,
"type_info": "Text"
}
@@ -70,5 +70,5 @@
false
]
},
"hash": "0b55273631c697e19f622a14d9f7c81c7c669744f3c586397f8d08eb924cae73"
"hash": "bc2603a54513425d0ab6fab1f2f58845650e51b5270c60a428a85f9e219f0ede"
}

View File

@@ -0,0 +1,20 @@
{
"db_name": "SQLite",
"query": "SELECT DISTINCT ta.id as \"id!: Uuid\"\n FROM task_attempts ta\n INNER JOIN (\n SELECT task_attempt_id, MAX(created_at) as latest_created_at\n FROM task_attempt_activities\n GROUP BY task_attempt_id\n ) latest_activity ON ta.id = latest_activity.task_attempt_id\n INNER JOIN task_attempt_activities taa ON ta.id = taa.task_attempt_id \n AND taa.created_at = latest_activity.latest_created_at\n WHERE taa.status = $1",
"describe": {
"columns": [
{
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Blob"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true
]
},
"hash": "d42bfe41f064f0463e3d07bf4dd6a19438864ed6982649073618246e30efee2f"
}

View File

@@ -1,17 +1,17 @@
{
"db_name": "SQLite",
"query": "SELECT id, project_id, title, description, status as \"status!: TaskStatus\", created_at, updated_at \n FROM tasks \n WHERE id = $1",
"query": "SELECT id as \"id!: Uuid\", project_id as \"project_id!: Uuid\", title, description, status as \"status!: TaskStatus\", created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"\n FROM tasks \n WHERE id = $1",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "project_id",
"name": "project_id!: Uuid",
"ordinal": 1,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "title",
@@ -29,12 +29,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 5,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 6,
"type_info": "Text"
}
@@ -52,5 +52,5 @@
false
]
},
"hash": "ff38912305d2082b153f12e0d59f0be12177a626b170b3ed3b41049b235cc57c"
"hash": "d7f5b59e70cc177ec547b5f2f185713f7a284b3dbc774f61d9d95dd830df34c0"
}

View File

@@ -1,44 +0,0 @@
{
"db_name": "SQLite",
"query": "SELECT id, task_attempt_id, status as \"status!: TaskAttemptStatus\", note, created_at \n FROM task_attempt_activities \n WHERE task_attempt_id = $1 \n ORDER BY created_at DESC",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
},
{
"name": "task_attempt_id",
"ordinal": 1,
"type_info": "Text"
},
{
"name": "status!: TaskAttemptStatus",
"ordinal": 2,
"type_info": "Text"
},
{
"name": "note",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "created_at",
"ordinal": 4,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true,
false,
false,
true,
false
]
},
"hash": "db4598a1164ee77414e789445f5da2384153bbade8ae677f60ea52d62875d23c"
}

View File

@@ -1,12 +1,12 @@
{
"db_name": "SQLite",
"query": "UPDATE projects SET name = $2, git_repo_path = $3 WHERE id = $1 RETURNING id, name, git_repo_path, created_at, updated_at",
"query": "UPDATE projects SET name = $2, git_repo_path = $3 WHERE id = $1 RETURNING id as \"id!: Uuid\", name, git_repo_path, created_at as \"created_at!: DateTime<Utc>\", updated_at as \"updated_at!: DateTime<Utc>\"",
"describe": {
"columns": [
{
"name": "id",
"name": "id!: Uuid",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
},
{
"name": "name",
@@ -19,12 +19,12 @@
"type_info": "Text"
},
{
"name": "created_at",
"name": "created_at!: DateTime<Utc>",
"ordinal": 3,
"type_info": "Text"
},
{
"name": "updated_at",
"name": "updated_at!: DateTime<Utc>",
"ordinal": 4,
"type_info": "Text"
}
@@ -40,5 +40,5 @@
false
]
},
"hash": "219898a7ca7dcdeceb9f248d95f0e4afe8128df16f57c3b91334ac4ce80b6e5a"
"hash": "eeede8a732db5214bb9054d6c2b7655989102264949864e719610f12cbb4c0c0"
}

View File

@@ -1,20 +0,0 @@
{
"db_name": "SQLite",
"query": "SELECT DISTINCT ta.id \n FROM task_attempts ta\n INNER JOIN (\n SELECT task_attempt_id, MAX(created_at) as latest_created_at\n FROM task_attempt_activities\n GROUP BY task_attempt_id\n ) latest_activity ON ta.id = latest_activity.task_attempt_id\n INNER JOIN task_attempt_activities taa ON ta.id = taa.task_attempt_id \n AND taa.created_at = latest_activity.latest_created_at\n WHERE taa.status = $1",
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
}
],
"parameters": {
"Right": 1
},
"nullable": [
true
]
},
"hash": "f72efcb41e92e03b8f8b988017d3b1c509322dc560742e9ef77fb9532b748fce"
}

View File

@@ -6,7 +6,7 @@
{
"name": "id",
"ordinal": 0,
"type_info": "Text"
"type_info": "Blob"
}
],
"parameters": {

View File

@@ -1,20 +1,7 @@
-- Turn on FK support (important for SQLite)
PRAGMA foreign_keys = ON;
-------------------------------------------------------------------------------
-- 1. Core lookup “enums” (via CHECK constraints)
-------------------------------------------------------------------------------
-- task_status values
-- ('todo','inprogress','done','cancelled','inreview')
-- task_attempt_status values
-- ('init','inprogress','paused')
-------------------------------------------------------------------------------
-- 2. Tables
-------------------------------------------------------------------------------
CREATE TABLE projects (
id TEXT PRIMARY KEY, -- UUID as string
id BLOB PRIMARY KEY,
name TEXT NOT NULL,
git_repo_path TEXT NOT NULL DEFAULT '' UNIQUE,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -22,8 +9,8 @@ CREATE TABLE projects (
);
CREATE TABLE tasks (
id TEXT PRIMARY KEY,
project_id TEXT NOT NULL,
id BLOB PRIMARY KEY,
project_id BLOB NOT NULL,
title TEXT NOT NULL,
description TEXT,
status TEXT NOT NULL DEFAULT 'todo'
@@ -34,12 +21,12 @@ CREATE TABLE tasks (
);
CREATE TABLE task_attempts (
id TEXT PRIMARY KEY,
task_id TEXT NOT NULL,
id BLOB PRIMARY KEY,
task_id BLOB NOT NULL,
worktree_path TEXT NOT NULL,
base_commit TEXT,
merge_commit TEXT,
executor TEXT, -- final column name (no JSONB)
executor TEXT,
stdout TEXT,
stderr TEXT,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
@@ -48,52 +35,11 @@ CREATE TABLE task_attempts (
);
CREATE TABLE task_attempt_activities (
id TEXT PRIMARY KEY,
task_attempt_id TEXT NOT NULL,
id BLOB PRIMARY KEY,
task_attempt_id BLOB NOT NULL,
status TEXT NOT NULL DEFAULT 'init'
CHECK (status IN ('init','inprogress','paused')),
note TEXT,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (task_attempt_id) REFERENCES task_attempts(id) ON DELETE CASCADE
);
-------------------------------------------------------------------------------
-- 3. Indexes
-------------------------------------------------------------------------------
CREATE INDEX idx_tasks_project_id ON tasks(project_id);
CREATE INDEX idx_tasks_status ON tasks(status);
CREATE INDEX idx_task_attempts_task_id ON task_attempts(task_id);
CREATE INDEX idx_task_attempt_activities_attempt_id ON task_attempt_activities(task_attempt_id);
CREATE INDEX idx_task_attempt_activities_status ON task_attempt_activities(status);
CREATE INDEX idx_task_attempt_activities_created_at ON task_attempt_activities(created_at);
-------------------------------------------------------------------------------
-- 4. updated_at auto-maintenance triggers
-- (fires only when caller hasnt manually changed updated_at)
-------------------------------------------------------------------------------
-- Projects
CREATE TRIGGER trg_projects_updated_at
AFTER UPDATE ON projects
FOR EACH ROW
WHEN NEW.updated_at = OLD.updated_at
BEGIN
UPDATE projects SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id;
END;
-- Tasks
CREATE TRIGGER trg_tasks_updated_at
AFTER UPDATE ON tasks
FOR EACH ROW
WHEN NEW.updated_at = OLD.updated_at
BEGIN
UPDATE tasks SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id;
END;
-- Task attempts
CREATE TRIGGER trg_task_attempts_updated_at
AFTER UPDATE ON task_attempts
FOR EACH ROW
WHEN NEW.updated_at = OLD.updated_at
BEGIN
UPDATE task_attempts SET updated_at = CURRENT_TIMESTAMP WHERE id = OLD.id;
END;

View File

@@ -121,9 +121,9 @@ impl Project {
}
pub async fn exists(pool: &SqlitePool, id: Uuid) -> Result<bool, sqlx::Error> {
let result = sqlx::query!("SELECT id FROM projects WHERE id = $1", id)
.fetch_optional(pool)
let result = sqlx::query!("SELECT COUNT(*) as count FROM projects WHERE id = $1", id)
.fetch_one(pool)
.await?;
Ok(result.is_some())
Ok(result.count > 0)
}
}

View File

@@ -200,10 +200,11 @@ impl Task {
}
pub async fn delete(pool: &SqlitePool, id: Uuid, project_id: Uuid) -> Result<u64, sqlx::Error> {
let project_id_str = project_id.to_string();
let result = sqlx::query!(
"DELETE FROM tasks WHERE id = $1 AND project_id = $2",
id,
project_id
project_id_str
)
.execute(pool)
.await?;
@@ -215,10 +216,12 @@ impl Task {
id: Uuid,
project_id: Uuid,
) -> Result<bool, sqlx::Error> {
let id_str = id.to_string();
let project_id_str = project_id.to_string();
let result = sqlx::query!(
"SELECT id FROM tasks WHERE id = $1 AND project_id = $2",
id,
project_id
id_str,
project_id_str
)
.fetch_optional(pool)
.await?;