diff --git a/backend/modules/tasks/operations/subtasks.js b/backend/modules/tasks/operations/subtasks.js index b1c1bb8..54b8813 100644 --- a/backend/modules/tasks/operations/subtasks.js +++ b/backend/modules/tasks/operations/subtasks.js @@ -92,6 +92,26 @@ async function updateSubtasks(taskId, subtasks, userId) { ); if (subtasksToDelete.length > 0) { + if ( + subtasksToDelete.length === existingSubtasks.length && + subtasks.length === 0 + ) { + logError( + 'WARNING: Attempting to delete all subtasks with empty array:', + { + taskId, + userId, + existingCount: existingSubtasks.length, + providedCount: subtasks.length, + subtasksToDelete: subtasksToDelete.map((s) => ({ + id: s.id, + name: s.name, + parent_task_id: s.parent_task_id, + })), + } + ); + } + await taskRepository.destroyMany({ where: { id: subtasksToDelete.map((s) => s.id), diff --git a/backend/modules/tasks/utils/validation.js b/backend/modules/tasks/utils/validation.js index ea6d7d3..73cd911 100644 --- a/backend/modules/tasks/utils/validation.js +++ b/backend/modules/tasks/utils/validation.js @@ -36,7 +36,18 @@ async function validateParentTaskAccess(parentTaskId, userId) { where: { id: parentTaskId, user_id: userId }, }); if (!parentTask) { - throw new Error('Invalid parent task.'); + const anyTask = await Task.findOne({ + where: { id: parentTaskId }, + }); + if (anyTask) { + throw new Error( + `Invalid parent task. Parent task exists but belongs to a different user (parent user_id: ${anyTask.user_id}, current user_id: ${userId}).` + ); + } else { + throw new Error( + `Invalid parent task. Parent task with id ${parentTaskId} not found.` + ); + } } const parentAccess = await permissionsService.getAccess( @@ -49,7 +60,7 @@ async function validateParentTaskAccess(parentTaskId, userId) { isOwner || parentAccess === 'rw' || parentAccess === 'admin'; if (!canWrite) { - throw new Error('Invalid parent task.'); + throw new Error('Invalid parent task. Insufficient permissions.'); } return parentTaskId; diff --git a/frontend/components/Task/TaskDetails.tsx b/frontend/components/Task/TaskDetails.tsx index ffd2c82..b849cc8 100644 --- a/frontend/components/Task/TaskDetails.tsx +++ b/frontend/components/Task/TaskDetails.tsx @@ -1062,7 +1062,10 @@ const TaskDetails: React.FC = () => { ); if (existingIndex >= 0) { const updatedTasks = [...tasksStore.tasks]; - updatedTasks[existingIndex] = updatedTask; + updatedTasks[existingIndex] = { + ...updatedTask, + subtasks: updatedTask.subtasks || task.subtasks || [], + }; tasksStore.setTasks(updatedTasks); } }