Fixed! The issue was in the SQL query in [backend/src/models/task.rs](file:///private/var/folders/kr/jdxkcn7129j376nrg0stj9zm0000gn/T/vk-d725-failed-att/backend/src/models/task.rs#L134-L169). The failed_attempts subquery was checking for ANY failed attempt, but now it: (#73)

1. First gets the latest attempt for each task (using `ROW_NUMBER() OVER (PARTITION BY task_id ORDER BY created_at DESC)`)
2. Only considers non-merged attempts (`WHERE merge_commit IS NULL`)
3. Only shows the failed indicator if the latest attempt has failed

Now the red circle cross will only appear for tasks where the most recent attempt failed, not for any task that has ever had a failed attempt.
This commit is contained in:
Louis Knight-Webb
2025-07-04 14:01:51 +01:00
committed by GitHub
parent 597cefbf97
commit d3b9385c90
2 changed files with 13 additions and 7 deletions

View File

@@ -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<Utc>\", \n t.updated_at AS \"updated_at!: DateTime<Utc>\",\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 runningstates 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 runningstates 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<Utc>\", \n t.updated_at AS \"updated_at!: DateTime<Utc>\",\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 runningstates 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 runningstates 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"
}

View File

@@ -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 runningstates 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