LinkDesk/backend/docs/custom-task-status-delete-e...

4.5 KiB

Custom Task Status DELETE Endpoint Implementation

Overview

Implemented the DELETE endpoint for removing custom task statuses from projects with comprehensive validation and task reassignment support.

Endpoint Details

DELETE /projects/{project_id}/task-statuses/{status_id}

Authentication Required: Coordinator or Admin

Query Parameters:

  • reassign_to_status_id (optional): Status ID to reassign tasks to if the status being deleted is in use

Response: 200 OK with CustomTaskStatusResponse containing:

  • Success message
  • All remaining statuses (system + custom)
  • Updated default status ID

Implementation Features

1. Status In-Use Check

  • Queries all tasks in the project to check if any use the status being deleted
  • Returns detailed error (422) if status is in use and no reassignment provided:
    {
      "error": "Cannot delete status 'X' because it is currently in use by N task(s)",
      "status_id": "custom_abc123",
      "status_name": "In Review",
      "task_count": 5,
      "task_ids": [1, 2, 3, 4, 5]
    }
    

2. Task Reassignment

  • Supports optional reassign_to_status_id query parameter
  • Validates reassignment target exists (can be system or custom status)
  • Prevents reassigning to the same status being deleted
  • Automatically updates all affected tasks to the new status
  • Includes reassignment count in success message

3. Default Status Management

  • Detects if the status being deleted is the default status
  • Automatically assigns the first remaining custom status as the new default
  • Ensures there's always a default status after deletion

4. Last Status Protection

  • Prevents deletion of the last custom status
  • Returns 422 error with clear message
  • Ensures at least one custom status always remains

5. Error Handling

  • 404: Status not found
  • 404: Project not found
  • 400: Invalid reassignment status ID
  • 422: Status in use without reassignment
  • 422: Attempting to delete last status
  • 500: Database operation failure

Code Structure

@router.delete("/{project_id}/task-statuses/{status_id}")
async def delete_custom_task_status(
    project_id: int,
    status_id: str,
    reassign_to_status_id: Optional[str] = Query(None),
    db: Session = Depends(get_db),
    current_user: User = Depends(require_coordinator_or_admin)
):
    # 1. Verify project exists
    # 2. Load custom statuses from JSON
    # 3. Find status to delete
    # 4. Prevent deletion of last status
    # 5. Check if status is in use
    # 6. Handle reassignment if needed
    # 7. Auto-assign new default if needed
    # 8. Update database with flag_modified
    # 9. Return success response with all statuses

Test Coverage

Comprehensive test suite in test_delete_custom_task_status.py:

  1. Delete unused custom status
  2. Delete status in use without reassignment (error)
  3. Delete status in use with reassignment
  4. Delete default status (auto-assign new default)
  5. Prevent deletion of last status
  6. Delete non-existent status (error)

Requirements Validation

3.1: Check if status is in use by any tasks 3.2: Return error with task count and IDs if in use 3.3: Support optional reassignment of tasks to another status 3.4: Auto-assign new default if deleting default status 3.5: Prevent deletion of last status

Database Considerations

  • Uses flag_modified() for JSON column updates (required for SQLAlchemy to detect changes)
  • Transactional: All changes (status deletion + task reassignments) happen in one transaction
  • Rollback on any error to maintain data consistency

Usage Examples

Delete unused status

DELETE /projects/1/task-statuses/custom_abc123

Delete status with reassignment

DELETE /projects/1/task-statuses/custom_abc123?reassign_to_status_id=not_started

Delete status with reassignment to another custom status

DELETE /projects/1/task-statuses/custom_abc123?reassign_to_status_id=custom_xyz789

Integration Notes

  • Works seamlessly with existing custom status endpoints (GET, POST, PUT)
  • Maintains consistency with system statuses (cannot delete system statuses)
  • Properly updates the AllTaskStatusesResponse to reflect changes
  • Frontend can use the returned all_statuses to update UI immediately

Future Enhancements

Potential improvements for future iterations:

  • Bulk delete with single reassignment target
  • Soft delete with archive functionality
  • Status usage analytics before deletion
  • Undo/restore deleted statuses