# Task 5 Requirements Checklist

## Task: Backend: Implement PUT endpoint for updating custom status

### Requirements Coverage

#### ✅ Requirement 2.1: Support updating name

**Implementation:**
```python
# Validate name uniqueness if name is being changed
if status_update.name is not None and status_update.name != status_to_update.get('name'):
    # Check against other custom statuses
    existing_names = [
        s.get('name', '').lower() 
        for i, s in enumerate(custom_statuses_data) 
        if isinstance(s, dict) and i != status_index
    ]
    
    # Check against system statuses
    system_names = [s['name'].lower() for s in SYSTEM_TASK_STATUSES]
    
    if status_update.name.lower() in existing_names:
        raise HTTPException(status_code=409, ...)
    
    if status_update.name.lower() in system_names:
        raise HTTPException(status_code=409, ...)
    
    # Update name
    status_to_update['name'] = status_update.name
```

**Verified:**
- ✅ Name can be updated
- ✅ Name validation works
- ✅ Uniqueness check implemented
- ✅ Returns updated status

---

#### ✅ Requirement 2.2: Support updating color

**Implementation:**
```python
# Update color if provided
if status_update.color is not None:
    status_to_update['color'] = status_update.color
```

**Verified:**
- ✅ Color can be updated
- ✅ Color format validated by schema (hex codes)
- ✅ Color updates independently of other fields
- ✅ Returns updated status

---

#### ✅ Requirement 2.3: Support updating is_default flag

**Implementation:**
```python
# Handle is_default flag
if status_update.is_default is not None:
    if status_update.is_default:
        # If setting as default, unset other default statuses
        for status_data in custom_statuses_data:
            if isinstance(status_data, dict):
                status_data['is_default'] = False
        
        # Set this status as default
        status_to_update['is_default'] = True
    else:
        # Just unset this status as default
        status_to_update['is_default'] = False
```

**Verified:**
- ✅ is_default flag can be updated
- ✅ Can set status as default
- ✅ Can unset status as default
- ✅ Returns updated status

---

#### ✅ Requirement 5.2: If setting as default, unset other default statuses

**Implementation:**
```python
if status_update.is_default:
    # If setting as default, unset other default statuses
    for status_data in custom_statuses_data:
        if isinstance(status_data, dict):
            status_data['is_default'] = False
    
    # Set this status as default
    status_to_update['is_default'] = True
```

**Verified:**
- ✅ When setting a status as default, all other defaults are unset
- ✅ Only one default status exists at a time
- ✅ Default status ID is correctly returned in response
- ✅ Previous default is properly unset

---

#### ✅ Additional Requirement: Validate name uniqueness if name is changed

**Implementation:**
```python
# Validate name uniqueness if name is being changed
if status_update.name is not None and status_update.name != status_to_update.get('name'):
    # Check against other custom statuses
    existing_names = [...]
    
    # Check against system statuses
    system_names = [...]
    
    if status_update.name.lower() in existing_names:
        raise HTTPException(status_code=409, ...)
    
    if status_update.name.lower() in system_names:
        raise HTTPException(status_code=409, ...)
```

**Verified:**
- ✅ Name uniqueness validated within project
- ✅ Checks against other custom statuses
- ✅ Checks against system status names
- ✅ Returns 409 Conflict on duplicate

---

#### ✅ Additional Requirement: Use flag_modified for JSON column updates

**Implementation:**
```python
# Update the status in the list
custom_statuses_data[status_index] = status_to_update
db_project.custom_task_statuses = custom_statuses_data

# Use flag_modified for JSON column updates
flag_modified(db_project, 'custom_task_statuses')

try:
    db.commit()
    db.refresh(db_project)
except Exception as e:
    db.rollback()
    raise HTTPException(...)
```

**Verified:**
- ✅ flag_modified is used
- ✅ Changes persist to database
- ✅ JSON column updates work correctly
- ✅ Rollback on error

---

### Endpoint Details

**Route:** `PUT /projects/{project_id}/task-statuses/{status_id}`

**Authorization:** Requires coordinator or admin role

**Request Body:**
```json
{
    "name": "string (optional)",
    "color": "string (optional)",
    "is_default": "boolean (optional)"
}
```

**Response:** `CustomTaskStatusResponse`
```json
{
    "message": "string",
    "status": { ... },
    "all_statuses": { ... }
}
```

**Error Codes:**
- 404: Project or status not found
- 409: Name conflict (duplicate or system status)
- 403: Insufficient permissions
- 422: Invalid request body

---

### Test Coverage

**Manual Tests Created:**
- ✅ `test_update_status_manual.py` - Comprehensive manual test script
- ✅ Tests all requirements
- ✅ Tests error conditions
- ✅ Tests edge cases

**Documentation Created:**
- ✅ `custom-task-status-update-endpoint.md` - Complete API documentation
- ✅ `task-5-implementation-summary.md` - Implementation summary
- ✅ `task-5-requirements-checklist.md` - This checklist

---

### Code Quality

**Validation:**
- ✅ No syntax errors
- ✅ No linting errors
- ✅ Follows existing code patterns
- ✅ Proper error handling
- ✅ Comprehensive validation
- ✅ Clear error messages

**Best Practices:**
- ✅ Uses dependency injection
- ✅ Proper authorization checks
- ✅ Transaction management (commit/rollback)
- ✅ Input validation via Pydantic schemas
- ✅ Consistent response format
- ✅ Proper HTTP status codes

---

## Summary

✅ **All requirements implemented and verified**

The PUT endpoint for updating custom task statuses has been successfully implemented with:
- Full support for updating name, color, and is_default flag
- Comprehensive validation (uniqueness, format, conflicts)
- Proper default status management (only one default at a time)
- Correct JSON column updates using flag_modified
- Complete error handling and authorization
- Comprehensive documentation and test scripts

**Task Status:** ✅ COMPLETED
