Init Repo
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
# Custom Task Status Creation Endpoint Implementation
|
||||
|
||||
## Overview
|
||||
Implemented the POST endpoint for creating custom task statuses in projects. This allows coordinators and admins to define project-specific task statuses beyond the built-in system statuses.
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### Endpoint
|
||||
- **Route**: `POST /projects/{project_id}/task-statuses`
|
||||
- **Status Code**: 201 Created
|
||||
- **Authorization**: Requires coordinator or admin role
|
||||
|
||||
### Features Implemented
|
||||
|
||||
#### 1. Status Name Uniqueness Validation
|
||||
- Validates that the status name is unique within the project
|
||||
- Case-insensitive comparison to prevent duplicates like "In Review" and "in review"
|
||||
- Checks against both existing custom statuses and system statuses
|
||||
- Returns 409 Conflict if duplicate found
|
||||
|
||||
#### 2. Auto-Assign Color from Palette
|
||||
- Defines a default color palette with 10 distinct colors:
|
||||
- Purple (#8B5CF6)
|
||||
- Pink (#EC4899)
|
||||
- Teal (#14B8A6)
|
||||
- Orange (#F97316)
|
||||
- Cyan (#06B6D4)
|
||||
- Lime (#84CC16)
|
||||
- Violet (#A855F7)
|
||||
- Rose (#F43F5E)
|
||||
- Sky (#22D3EE)
|
||||
- Yellow (#FACC15)
|
||||
- Automatically assigns the first unused color from the palette
|
||||
- If all colors are used, cycles back through the palette
|
||||
- Users can override by providing a custom color in hex format
|
||||
|
||||
#### 3. Unique Status ID Generation
|
||||
- Generates unique IDs using UUID4 with format: `custom_{8-char-hex}`
|
||||
- Example: `custom_0c7ba931`
|
||||
- Ensures no ID collisions
|
||||
|
||||
#### 4. JSON Column Updates
|
||||
- Uses SQLAlchemy's `flag_modified()` to properly track changes to JSON columns
|
||||
- Ensures database updates are persisted correctly
|
||||
|
||||
#### 5. Status Ordering
|
||||
- Automatically assigns order based on existing statuses
|
||||
- New statuses are appended to the end (max_order + 1)
|
||||
- Maintains consistent ordering for UI display
|
||||
|
||||
### Request Schema
|
||||
```json
|
||||
{
|
||||
"name": "Ready for Review",
|
||||
"color": "#8B5CF6" // Optional - auto-assigned if not provided
|
||||
}
|
||||
```
|
||||
|
||||
### Response Schema
|
||||
```json
|
||||
{
|
||||
"message": "Custom task status 'Ready for Review' created successfully",
|
||||
"status": {
|
||||
"id": "custom_0c7ba931",
|
||||
"name": "Ready for Review",
|
||||
"color": "#EC4899",
|
||||
"order": 3,
|
||||
"is_default": false
|
||||
},
|
||||
"all_statuses": {
|
||||
"statuses": [...], // All custom statuses
|
||||
"system_statuses": [...], // Built-in system statuses
|
||||
"default_status_id": "not_started"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Validation Rules
|
||||
|
||||
#### Name Validation (via Pydantic schema)
|
||||
- Minimum length: 1 character
|
||||
- Maximum length: 50 characters
|
||||
- Whitespace is trimmed
|
||||
- Cannot be empty after trimming
|
||||
|
||||
#### Color Validation (via Pydantic schema)
|
||||
- Must be valid hex color code format: `#RRGGBB`
|
||||
- Example: `#FF5733`
|
||||
- Normalized to uppercase
|
||||
- Optional field
|
||||
|
||||
### Error Responses
|
||||
|
||||
#### 404 Not Found
|
||||
```json
|
||||
{
|
||||
"detail": "Project not found"
|
||||
}
|
||||
```
|
||||
|
||||
#### 409 Conflict - Duplicate Name
|
||||
```json
|
||||
{
|
||||
"detail": "Status with name 'Ready for Review' already exists in this project"
|
||||
}
|
||||
```
|
||||
|
||||
#### 409 Conflict - System Status Name
|
||||
```json
|
||||
{
|
||||
"detail": "Status name 'In Progress' conflicts with a system status"
|
||||
}
|
||||
```
|
||||
|
||||
#### 422 Unprocessable Entity - Validation Error
|
||||
```json
|
||||
{
|
||||
"detail": "1 validation error for CustomTaskStatusCreate\nname\n String should have at least 1 character..."
|
||||
}
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Results
|
||||
All validation and functionality tests passed:
|
||||
|
||||
1. ✅ Create status without color (auto-assigned from palette)
|
||||
2. ✅ Create status with custom color
|
||||
3. ✅ Reject duplicate status names (409 Conflict)
|
||||
4. ✅ Reject empty status names (422 Validation Error)
|
||||
5. ✅ Reject invalid color formats (422 Validation Error)
|
||||
6. ✅ Reject system status name conflicts (409 Conflict)
|
||||
7. ✅ Proper ordering of statuses
|
||||
8. ✅ Unique ID generation
|
||||
9. ✅ JSON column updates with flag_modified
|
||||
|
||||
### Test Files
|
||||
- `backend/test_create_custom_task_status.py` - Comprehensive test suite
|
||||
- `backend/test_custom_status_validation.py` - Validation-focused tests
|
||||
|
||||
## Database Schema
|
||||
The custom task statuses are stored in the `projects.custom_task_statuses` JSON column:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": "custom_review",
|
||||
"name": "In Review",
|
||||
"color": "#8B5CF6",
|
||||
"order": 0,
|
||||
"is_default": false
|
||||
},
|
||||
{
|
||||
"id": "custom_blocked",
|
||||
"name": "Blocked",
|
||||
"color": "#DC2626",
|
||||
"order": 1,
|
||||
"is_default": false
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Requirements Satisfied
|
||||
- ✅ Requirement 1.2: Create new custom task status
|
||||
- ✅ Requirement 1.3: Validate status name uniqueness within project
|
||||
- ✅ Requirement 1.4: Auto-assign color from palette if not provided
|
||||
|
||||
## Next Steps
|
||||
The following endpoints still need to be implemented:
|
||||
- PUT endpoint for updating custom status (Task 5)
|
||||
- DELETE endpoint for deleting custom status (Task 6)
|
||||
- PATCH endpoint for reordering statuses (Task 7)
|
||||
Reference in New Issue
Block a user