LinkDesk/frontend/docs/custom-task-delete-fix.md

4.5 KiB

Custom Task Type Delete Fix

Problem

When attempting to delete a custom task type (asset or shot) from the frontend, a "Method Not Allowed" (405) error was returned.

Root Cause

The issue had three parts:

  1. Missing Query Parameter Declaration (Backend): The category parameter in the delete endpoint wasn't explicitly declared as a query parameter using FastAPI's Query() annotation.

  2. Incorrect Response Format (Backend): All three custom task type endpoints (add, update, delete) were returning simple dictionaries instead of the AllTaskTypesResponse format that the frontend expected.

  3. Dialog Event Handler Bug (Frontend): The @update:open="closeDeleteDialog" handler was clearing taskTypeToDelete when the dialog state changed for ANY reason, including when clicking the Delete button. This meant the task type value was cleared BEFORE the delete API call could use it, resulting in an empty URL path.

Solution

Backend Changes (backend/routers/projects.py)

  1. Added Query import:

    from fastapi import APIRouter, Depends, HTTPException, status, Query
    
  2. Created helper function to build consistent responses:

    def _build_all_task_types_response(db_project: Project):
        """Helper function to build AllTaskTypesResponse"""
        from schemas.custom_task_type import AllTaskTypesResponse
    
        custom_asset_types = db_project.custom_asset_task_types or []
        custom_shot_types = db_project.custom_shot_task_types or []
    
        all_asset_types = STANDARD_ASSET_TASK_TYPES + custom_asset_types
        all_shot_types = STANDARD_SHOT_TASK_TYPES + custom_shot_types
    
        return AllTaskTypesResponse(
            asset_task_types=all_asset_types,
            shot_task_types=all_shot_types,
            standard_asset_types=STANDARD_ASSET_TASK_TYPES,
            standard_shot_types=STANDARD_SHOT_TASK_TYPES,
            custom_asset_types=custom_asset_types,
            custom_shot_types=custom_shot_types
        )
    
  3. Updated delete endpoint signature:

    @router.delete("/{project_id}/custom-task-types/{task_type}")
    async def delete_custom_task_type(
        project_id: int,
        task_type: str,
        category: str = Query(..., description="Category: 'asset' or 'shot'"),  # ← Explicit query param
        db: Session = Depends(get_db),
        current_user: User = Depends(require_coordinator_or_admin)
    ):
    
  4. Updated all three endpoints to return AllTaskTypesResponse:

    • add_custom_task_type() - now returns _build_all_task_types_response(db_project)
    • update_custom_task_type() - now returns _build_all_task_types_response(db_project)
    • delete_custom_task_type() - now returns _build_all_task_types_response(db_project)

Frontend (No Changes Required)

The frontend service (frontend/src/services/customTaskType.ts) was already correctly sending the category as a query parameter:

async deleteCustomTaskType(projectId: number, taskType: string, category: 'asset' | 'shot'): Promise<AllTaskTypesResponse> {
  const encodedTaskType = encodeURIComponent(taskType)
  const response = await apiClient.delete(`/projects/${projectId}/custom-task-types/${encodedTaskType}`, {
    params: { category }  // ← Correctly sends as query param
  })
  return response.data
}

Testing

Restart Backend Server

IMPORTANT: The backend server must be restarted for changes to take effect:

cd backend
uvicorn main:app --reload --host 0.0.0.0 --port 8000

Test Methods

  1. Via Frontend UI:

    • Navigate to Project Settings → Custom Task Types
    • Add a custom task type
    • Click the delete button
    • Should now work without "Method Not Allowed" error
  2. Via Test HTML Page:

    • Open frontend/test-delete-custom-task.html in browser
    • Follow the 4-step test process
    • Verify delete works correctly
  3. Via Python Test Script:

    cd backend
    python test_delete_fix.py
    

Expected Behavior

After the fix:

  • Delete button works for custom task types
  • Returns updated list of all task types
  • Frontend automatically refreshes the UI with updated list
  • Consistent response format across all custom task type operations

Files Modified

  • backend/routers/projects.py - Fixed delete endpoint and response formats
  • backend/test_delete_fix.py - Created test script
  • frontend/test-delete-custom-task.html - Created browser test page
  • frontend/docs/custom-task-delete-fix.md - This documentation