LinkDesk/backend/docs/task-5-requirements-checkli...

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