241 lines
6.1 KiB
Markdown
241 lines
6.1 KiB
Markdown
# 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
|