diff --git a/backend/.sqlx/query-b7d9fc7198a30ad4e88d7cdd7b59a1a73018de16506003622cd7f779028c0fa8.json b/backend/.sqlx/query-9c615a14edb0886be82b9004961205da09c67a18907bbf562b6177f8bc8bc0bc.json similarity index 66% rename from backend/.sqlx/query-b7d9fc7198a30ad4e88d7cdd7b59a1a73018de16506003622cd7f779028c0fa8.json rename to backend/.sqlx/query-9c615a14edb0886be82b9004961205da09c67a18907bbf562b6177f8bc8bc0bc.json index 6c779920..63883b07 100644 --- a/backend/.sqlx/query-b7d9fc7198a30ad4e88d7cdd7b59a1a73018de16506003622cd7f779028c0fa8.json +++ b/backend/.sqlx/query-9c615a14edb0886be82b9004961205da09c67a18907bbf562b6177f8bc8bc0bc.json @@ -1,6 +1,6 @@ { "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\", \n t.updated_at AS \"updated_at!: DateTime\",\n CASE \n WHEN in_progress_attempts.task_id IS NOT NULL THEN true \n ELSE false \n END AS \"has_in_progress_attempt!: i64\",\n CASE \n WHEN merged_attempts.task_id IS NOT NULL THEN true \n ELSE false \n END AS \"has_merged_attempt!\",\n CASE \n WHEN failed_attempts.task_id IS NOT NULL THEN true \n ELSE false \n END AS \"has_failed_attempt!\"\n FROM tasks t\n LEFT JOIN (\n SELECT DISTINCT ta.task_id\n FROM task_attempts ta\n JOIN execution_processes ep \n ON ta.id = ep.task_attempt_id\n JOIN (\n -- pick exactly one “latest” activity per process,\n -- tiebreaking so that running‐states are lower priority\n SELECT execution_process_id, status\n FROM (\n SELECT\n execution_process_id,\n status,\n ROW_NUMBER() OVER (\n PARTITION BY execution_process_id\n ORDER BY\n created_at DESC,\n CASE \n WHEN status IN ('setuprunning','executorrunning') THEN 1 \n ELSE 0 \n END\n ) AS rn\n FROM task_attempt_activities\n ) sub\n WHERE rn = 1\n ) latest_act \n ON ep.id = latest_act.execution_process_id\n WHERE latest_act.status IN ('setuprunning','executorrunning')\n ) in_progress_attempts \n ON t.id = in_progress_attempts.task_id\n LEFT JOIN (\n SELECT DISTINCT ta.task_id\n FROM task_attempts ta\n WHERE ta.merge_commit IS NOT NULL\n ) merged_attempts \n ON t.id = merged_attempts.task_id\n LEFT JOIN (\n SELECT DISTINCT ta.task_id\n FROM task_attempts ta\n JOIN execution_processes ep \n ON ta.id = ep.task_attempt_id\n JOIN (\n -- pick exactly one \"latest\" activity per process,\n -- tiebreaking so that running‐states are lower priority\n SELECT execution_process_id, status\n FROM (\n SELECT\n execution_process_id,\n status,\n ROW_NUMBER() OVER (\n PARTITION BY execution_process_id\n ORDER BY\n created_at DESC,\n CASE \n WHEN status IN ('setuprunning','executorrunning') THEN 1 \n ELSE 0 \n END\n ) AS rn\n FROM task_attempt_activities\n ) sub\n WHERE rn = 1\n ) latest_act \n ON ep.id = latest_act.execution_process_id\n WHERE latest_act.status IN ('setupfailed','executorfailed')\n AND ta.merge_commit IS NULL -- Don't show as failed if already merged\n ) failed_attempts \n ON t.id = failed_attempts.task_id\n WHERE t.project_id = $1\n ORDER BY t.created_at DESC;\n ", + "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\", \n t.updated_at AS \"updated_at!: DateTime\",\n CASE \n WHEN in_progress_attempts.task_id IS NOT NULL THEN true \n ELSE false \n END AS \"has_in_progress_attempt!: i64\",\n CASE \n WHEN merged_attempts.task_id IS NOT NULL THEN true \n ELSE false \n END AS \"has_merged_attempt!\",\n CASE \n WHEN failed_attempts.task_id IS NOT NULL THEN true \n ELSE false \n END AS \"has_failed_attempt!\"\n FROM tasks t\n LEFT JOIN (\n SELECT DISTINCT ta.task_id\n FROM task_attempts ta\n JOIN execution_processes ep \n ON ta.id = ep.task_attempt_id\n JOIN (\n -- pick exactly one “latest” activity per process,\n -- tiebreaking so that running‐states are lower priority\n SELECT execution_process_id, status\n FROM (\n SELECT\n execution_process_id,\n status,\n ROW_NUMBER() OVER (\n PARTITION BY execution_process_id\n ORDER BY\n created_at DESC,\n CASE \n WHEN status IN ('setuprunning','executorrunning') THEN 1 \n ELSE 0 \n END\n ) AS rn\n FROM task_attempt_activities\n ) sub\n WHERE rn = 1\n ) latest_act \n ON ep.id = latest_act.execution_process_id\n WHERE latest_act.status IN ('setuprunning','executorrunning')\n ) in_progress_attempts \n ON t.id = in_progress_attempts.task_id\n LEFT JOIN (\n SELECT DISTINCT ta.task_id\n FROM task_attempts ta\n WHERE ta.merge_commit IS NOT NULL\n ) merged_attempts \n ON t.id = merged_attempts.task_id\n LEFT JOIN (\n SELECT DISTINCT latest_attempts.task_id\n FROM (\n -- Get the latest attempt for each task\n SELECT task_id, id as attempt_id, created_at,\n ROW_NUMBER() OVER (PARTITION BY task_id ORDER BY created_at DESC) AS rn\n FROM task_attempts\n WHERE merge_commit IS NULL -- Don't show as failed if already merged\n ) latest_attempts\n JOIN execution_processes ep \n ON latest_attempts.attempt_id = ep.task_attempt_id\n JOIN (\n -- pick exactly one \"latest\" activity per process,\n -- tiebreaking so that running‐states are lower priority\n SELECT execution_process_id, status\n FROM (\n SELECT\n execution_process_id,\n status,\n ROW_NUMBER() OVER (\n PARTITION BY execution_process_id\n ORDER BY\n created_at DESC,\n CASE \n WHEN status IN ('setuprunning','executorrunning') THEN 1 \n ELSE 0 \n END\n ) AS rn\n FROM task_attempt_activities\n ) sub\n WHERE rn = 1\n ) latest_act \n ON ep.id = latest_act.execution_process_id\n WHERE latest_attempts.rn = 1 -- Only consider the latest attempt\n AND latest_act.status IN ('setupfailed','executorfailed')\n ) failed_attempts \n ON t.id = failed_attempts.task_id\n WHERE t.project_id = $1\n ORDER BY t.created_at DESC;\n ", "describe": { "columns": [ { @@ -70,5 +70,5 @@ false ] }, - "hash": "b7d9fc7198a30ad4e88d7cdd7b59a1a73018de16506003622cd7f779028c0fa8" + "hash": "9c615a14edb0886be82b9004961205da09c67a18907bbf562b6177f8bc8bc0bc" } diff --git a/backend/src/models/task.rs b/backend/src/models/task.rs index 7f98fb3a..aa56b149 100644 --- a/backend/src/models/task.rs +++ b/backend/src/models/task.rs @@ -132,10 +132,16 @@ impl Task { ) merged_attempts ON t.id = merged_attempts.task_id LEFT JOIN ( - SELECT DISTINCT ta.task_id - FROM task_attempts ta + SELECT DISTINCT latest_attempts.task_id + FROM ( + -- Get the latest attempt for each task + SELECT task_id, id as attempt_id, created_at, + ROW_NUMBER() OVER (PARTITION BY task_id ORDER BY created_at DESC) AS rn + FROM task_attempts + WHERE merge_commit IS NULL -- Don't show as failed if already merged + ) latest_attempts JOIN execution_processes ep - ON ta.id = ep.task_attempt_id + ON latest_attempts.attempt_id = ep.task_attempt_id JOIN ( -- pick exactly one "latest" activity per process, -- tiebreaking so that running‐states are lower priority @@ -158,8 +164,8 @@ impl Task { WHERE rn = 1 ) latest_act ON ep.id = latest_act.execution_process_id - WHERE latest_act.status IN ('setupfailed','executorfailed') - AND ta.merge_commit IS NULL -- Don't show as failed if already merged + WHERE latest_attempts.rn = 1 -- Only consider the latest attempt + AND latest_act.status IN ('setupfailed','executorfailed') ) failed_attempts ON t.id = failed_attempts.task_id WHERE t.project_id = $1