Perfect! All tasks have been completed successfully. Here's a summary of the changes: (#970)
Successfully implemented a better delete task workflow that properly handles task family relationships: 1. **Database Migration** (`crates/db/migrations/20251007000000_set_null_parent_task_attempt_on_delete.sql`): - Updated the `parent_task_attempt` foreign key constraint from the default behavior to `ON DELETE SET NULL` - This ensures that when a task attempt is deleted, child tasks are decoupled rather than deleted 2. **Backend - Database Layer** (`crates/db/src/models/task.rs`): - Added `find_children_by_parent_task_id()` method to find all child tasks created by any attempts of a given parent task 3. **Backend - API Layer** (`crates/server/src/routes/tasks.rs`): - Updated `delete_task()` endpoint to check for child tasks before deletion and log them - Added `get_task_children()` endpoint to fetch child tasks for a given task - Updated analytics to track the number of child tasks affected 4. **Frontend - API Client** (`frontend/src/lib/api.ts`): - Added `getChildren()` method to fetch child tasks for a given task 5. **Frontend - UI** (`frontend/src/components/dialogs/tasks/DeleteTaskConfirmationDialog.tsx`): - Added loading and display of child tasks before deletion - Shows a warning with the list of child tasks that will be decoupled - Displays up to 3 child task names with a count of remaining ones 6. **MCP Server** (`crates/server/src/mcp/task_server.rs`): - Updated `delete_task` tool description to clarify that child tasks are decoupled, not deleted - Updated success message to inform about decoupled children - When a task is deleted, all its attempts are deleted (CASCADE) - Child tasks that were created by those attempts have their `parent_task_attempt` set to NULL (decoupled) - The UI warns users about child tasks that will be affected - Child tasks remain in the project and can continue to be worked on independently All code compiles successfully and sqlx queries have been prepared.
This commit is contained in:
@@ -46,12 +46,12 @@
|
||||
{
|
||||
"name": "has_in_progress_attempt!: i64",
|
||||
"ordinal": 8,
|
||||
"type_info": "Null"
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "last_attempt_failed!: i64",
|
||||
"ordinal": 9,
|
||||
"type_info": "Null"
|
||||
"type_info": "Integer"
|
||||
},
|
||||
{
|
||||
"name": "executor!: String",
|
||||
@@ -71,8 +71,8 @@
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
PRAGMA foreign_keys = OFF;
|
||||
|
||||
-- Create new tasks table with updated foreign key constraint
|
||||
CREATE TABLE tasks_new (
|
||||
id BLOB PRIMARY KEY,
|
||||
project_id BLOB NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
description TEXT,
|
||||
status TEXT NOT NULL DEFAULT 'todo'
|
||||
CHECK (status IN ('todo','inprogress','done','cancelled','inreview')),
|
||||
parent_task_attempt BLOB,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now', 'subsec')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now', 'subsec')),
|
||||
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (parent_task_attempt) REFERENCES task_attempts(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
-- Copy data from old table to new table
|
||||
INSERT INTO tasks_new (id, project_id, title, description, status, parent_task_attempt, created_at, updated_at)
|
||||
SELECT id, project_id, title, description, status, parent_task_attempt, created_at, updated_at
|
||||
FROM tasks;
|
||||
|
||||
-- Drop old table
|
||||
DROP TABLE tasks;
|
||||
|
||||
-- Rename new table to original name
|
||||
ALTER TABLE tasks_new RENAME TO tasks;
|
||||
|
||||
-- Recreate index for parent_task_attempt lookups
|
||||
CREATE INDEX idx_tasks_parent_task_attempt ON tasks(parent_task_attempt);
|
||||
|
||||
PRAGMA foreign_keys = ON;
|
||||
Reference in New Issue
Block a user