195 lines
5.6 KiB
Markdown
195 lines
5.6 KiB
Markdown
# Custom Task Status GET Endpoint Implementation
|
|
|
|
## Overview
|
|
|
|
Implemented the GET endpoint for retrieving all task statuses (system + custom) for a project as part of the custom task status management feature.
|
|
|
|
## Endpoint Details
|
|
|
|
### GET /projects/{project_id}/task-statuses
|
|
|
|
**Description**: Retrieves all task statuses (both system and custom) for a specific project.
|
|
|
|
**Authentication**: Required (JWT Bearer token)
|
|
|
|
**Authorization**:
|
|
- Artists: Can only access projects they are members of
|
|
- Coordinators/Directors/Developers/Admins: Can access all projects
|
|
|
|
**Path Parameters**:
|
|
- `project_id` (int): The ID of the project
|
|
|
|
**Response Schema**: `AllTaskStatusesResponse`
|
|
```json
|
|
{
|
|
"statuses": [
|
|
{
|
|
"id": "custom_review",
|
|
"name": "In Review",
|
|
"color": "#8B5CF6",
|
|
"order": 0,
|
|
"is_default": false
|
|
}
|
|
],
|
|
"system_statuses": [
|
|
{
|
|
"id": "not_started",
|
|
"name": "Not Started",
|
|
"color": "#6B7280",
|
|
"is_system": true
|
|
},
|
|
{
|
|
"id": "in_progress",
|
|
"name": "In Progress",
|
|
"color": "#3B82F6",
|
|
"is_system": true
|
|
},
|
|
{
|
|
"id": "submitted",
|
|
"name": "Submitted",
|
|
"color": "#F59E0B",
|
|
"is_system": true
|
|
},
|
|
{
|
|
"id": "approved",
|
|
"name": "Approved",
|
|
"color": "#10B981",
|
|
"is_system": true
|
|
},
|
|
{
|
|
"id": "retake",
|
|
"name": "Retake",
|
|
"color": "#EF4444",
|
|
"is_system": true
|
|
}
|
|
],
|
|
"default_status_id": "not_started"
|
|
}
|
|
```
|
|
|
|
**Status Codes**:
|
|
- `200 OK`: Successfully retrieved task statuses
|
|
- `403 Forbidden`: User does not have access to the project
|
|
- `404 Not Found`: Project does not exist
|
|
|
|
## System Task Statuses
|
|
|
|
The following system statuses are always available:
|
|
|
|
| ID | Name | Color | Description |
|
|
|----|------|-------|-------------|
|
|
| not_started | Not Started | #6B7280 | Task has not been started |
|
|
| in_progress | In Progress | #3B82F6 | Task is currently being worked on |
|
|
| submitted | Submitted | #F59E0B | Work has been submitted for review |
|
|
| approved | Approved | #10B981 | Work has been approved |
|
|
| retake | Retake | #EF4444 | Work needs to be redone |
|
|
|
|
## Implementation Details
|
|
|
|
### Location
|
|
- File: `backend/routers/projects.py`
|
|
- Function: `get_all_task_statuses()`
|
|
|
|
### Key Features
|
|
|
|
1. **Project Validation**: Verifies the project exists before returning statuses
|
|
2. **Access Control**: Enforces role-based access control (artists can only access projects they're members of)
|
|
3. **System Statuses**: Always returns the 5 built-in system statuses
|
|
4. **Custom Statuses**: Returns project-specific custom statuses if defined
|
|
5. **Default Status**: Identifies which status is the default for new tasks
|
|
6. **JSON Handling**: Properly handles both JSON string and dict formats for custom_task_statuses field
|
|
|
|
### Database Schema
|
|
|
|
Custom statuses are stored in the `projects` table:
|
|
- Column: `custom_task_statuses` (JSON)
|
|
- Format: Array of status objects with id, name, color, order, and is_default fields
|
|
|
|
### Access Control Logic
|
|
|
|
```python
|
|
# Artists can only access projects they're members of
|
|
if current_user.role == UserRole.ARTIST:
|
|
member = db.query(ProjectMember).filter(
|
|
ProjectMember.project_id == project_id,
|
|
ProjectMember.user_id == current_user.id
|
|
).first()
|
|
if not member:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Access denied to this project"
|
|
)
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Test Files Created
|
|
|
|
1. **test_task_statuses.py**: Basic functionality test
|
|
- Tests retrieval of system statuses
|
|
- Validates response structure
|
|
- Verifies all system statuses are present
|
|
|
|
2. **test_task_statuses_with_custom.py**: Custom status test
|
|
- Creates custom statuses in database
|
|
- Tests retrieval of both system and custom statuses
|
|
- Validates default status identification
|
|
|
|
3. **test_task_statuses_access.py**: Access control test
|
|
- Tests artist access control (member vs non-member)
|
|
- Tests coordinator access to all projects
|
|
|
|
4. **test_task_statuses_errors.py**: Error handling test
|
|
- Tests 404 for non-existent projects
|
|
- Tests 401/403 for unauthorized access
|
|
|
|
### Test Results
|
|
|
|
All tests passed successfully:
|
|
- ✅ System statuses correctly returned
|
|
- ✅ Custom statuses correctly returned
|
|
- ✅ Default status correctly identified
|
|
- ✅ Access control working for artists
|
|
- ✅ Coordinators can access all projects
|
|
- ✅ 404 returned for non-existent projects
|
|
- ✅ Unauthorized access properly blocked
|
|
|
|
## Requirements Validation
|
|
|
|
This implementation satisfies the following requirements:
|
|
|
|
- **Requirement 1.1**: ✅ Displays task status information for project settings
|
|
- **Requirement 9.2**: ✅ Only shows statuses from the task's project (project-specific)
|
|
|
|
## Usage Example
|
|
|
|
```python
|
|
import requests
|
|
|
|
# Login
|
|
response = requests.post(
|
|
"http://localhost:8000/auth/login",
|
|
json={"email": "user@example.com", "password": "password"}
|
|
)
|
|
token = response.json()["access_token"]
|
|
|
|
# Get task statuses for project
|
|
response = requests.get(
|
|
"http://localhost:8000/projects/1/task-statuses",
|
|
headers={"Authorization": f"Bearer {token}"}
|
|
)
|
|
|
|
statuses = response.json()
|
|
print(f"System statuses: {len(statuses['system_statuses'])}")
|
|
print(f"Custom statuses: {len(statuses['statuses'])}")
|
|
print(f"Default status: {statuses['default_status_id']}")
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
The following endpoints still need to be implemented:
|
|
- POST /projects/{project_id}/task-statuses - Create custom status
|
|
- PUT /projects/{project_id}/task-statuses/{status_id} - Update custom status
|
|
- DELETE /projects/{project_id}/task-statuses/{status_id} - Delete custom status
|
|
- PATCH /projects/{project_id}/task-statuses/reorder - Reorder statuses
|