Init Repo
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user