LinkDesk/backend/docs/project-thumbnail-implement...

209 lines
6.0 KiB
Markdown

# Project Thumbnail Implementation
## Overview
This document describes the implementation of project thumbnail upload functionality for the VFX Project Management System.
## Requirements
Based on Requirement 2.1, the system allows coordinators and administrators to:
- Upload thumbnail images for projects
- Replace existing thumbnails
- Delete thumbnails
- View thumbnails on project cards
## Implementation Details
### 1. Database Changes
**Migration Script**: `backend/migrate_project_thumbnail.py`
Added `thumbnail_path` column to the `projects` table:
```sql
ALTER TABLE projects ADD COLUMN thumbnail_path VARCHAR
```
**Model Update**: `backend/models/project.py`
```python
thumbnail_path = Column(String, nullable=True) # Path to project thumbnail image
```
### 2. API Endpoints
#### Upload Thumbnail
**Endpoint**: `POST /api/projects/{project_id}/thumbnail`
**Access**: Coordinators and Admins only
**Request**: Multipart form data with image file
**Response**:
```json
{
"message": "Thumbnail uploaded successfully",
"thumbnail_url": "/api/files/projects/{project_id}/thumbnail"
}
```
**Features**:
- Validates file format (jpg, jpeg, png, gif, webp)
- Validates file size (max 10MB)
- Processes and resizes images to max 800x600 while maintaining aspect ratio
- Converts images with transparency to RGB with white background
- Generates unique filenames with timestamp and hash
- Automatically deletes old thumbnail when uploading new one
- Stores processed images in `uploads/project_thumbnails/`
#### Delete Thumbnail
**Endpoint**: `DELETE /api/projects/{project_id}/thumbnail`
**Access**: Coordinators and Admins only
**Response**: 204 No Content
**Features**:
- Removes thumbnail file from filesystem
- Clears `thumbnail_path` in database
- Returns 404 if project has no thumbnail
#### Serve Thumbnail
**Endpoint**: `GET /api/files/projects/{project_id}/thumbnail`
**Access**: All authenticated users (with project access)
**Response**: Image file with appropriate content-type
**Features**:
- Checks user has access to the project
- Artists can only access thumbnails for projects they're members of
- Returns 404 if thumbnail doesn't exist
- Serves image with proper MIME type
### 3. Schema Updates
**File**: `backend/schemas/project.py`
Added `thumbnail_url` field to response schemas:
```python
class ProjectResponse(ProjectBase):
# ... existing fields ...
thumbnail_url: Optional[str] = None
class ProjectListResponse(BaseModel):
# ... existing fields ...
thumbnail_url: Optional[str] = None
```
### 4. Router Updates
**File**: `backend/routers/projects.py`
Updated project endpoints to include thumbnail URL:
```python
# In list_projects
if project.thumbnail_path:
project_data.thumbnail_url = f"/api/files/projects/{project.id}/thumbnail"
# In get_project
if project.thumbnail_path:
project_data.thumbnail_url = f"/api/files/projects/{project.id}/thumbnail"
# In update_project
'thumbnail_url': f"/api/files/projects/{db_project.id}/thumbnail" if db_project.thumbnail_path else None
```
## File Storage Structure
```
backend/
└── uploads/
└── project_thumbnails/
├── project_1_20241119_123456_a1b2c3d4.jpg
├── project_2_20241119_123457_e5f6g7h8.jpg
└── ...
```
## Image Processing
The system processes uploaded thumbnails as follows:
1. **Format Validation**: Only accepts jpg, jpeg, png, gif, webp
2. **Size Validation**: Maximum 10MB file size
3. **Color Conversion**: Converts RGBA/LA/P modes to RGB with white background
4. **Resizing**: Maintains aspect ratio while fitting within 800x600 pixels
5. **Optimization**: Saves as JPEG with 90% quality and optimization enabled
## Access Control
| Role | Upload | Delete | View |
|------|--------|--------|------|
| Admin | ✓ | ✓ | ✓ |
| Coordinator | ✓ | ✓ | ✓ |
| Director | ✗ | ✗ | ✓ |
| Artist | ✗ | ✗ | ✓ (own projects only) |
| Developer | ✗ | ✗ | ✓ |
## Testing
A test script is provided at `backend/test_project_thumbnail.py` that verifies:
1. Thumbnail upload
2. Thumbnail URL in project responses
3. Thumbnail download
4. Thumbnail deletion
5. Thumbnail removal verification
To run the test:
```bash
cd backend
python test_project_thumbnail.py
```
**Note**: The backend server must be running on `http://localhost:8000`
## Error Handling
| Error | Status Code | Description |
|-------|-------------|-------------|
| Invalid file format | 400 | File extension not in allowed list |
| File too large | 413 | File exceeds 10MB limit |
| Image processing failed | 400 | PIL failed to process image |
| Project not found | 404 | Invalid project_id |
| No thumbnail | 404 | Project has no thumbnail |
| Access denied | 403 | User lacks permission |
## Frontend Integration
The frontend can now:
1. Display thumbnails on project cards using `project.thumbnail_url`
2. Upload thumbnails in project settings
3. Replace existing thumbnails
4. Remove thumbnails
5. Show placeholder when no thumbnail exists
Example usage:
```typescript
// Display thumbnail
<img :src="project.thumbnail_url || '/default-project-thumbnail.png'" />
// Upload thumbnail
const formData = new FormData()
formData.append('file', file)
await apiClient.post(`/projects/${projectId}/thumbnail`, formData)
// Delete thumbnail
await apiClient.delete(`/projects/${projectId}/thumbnail`)
```
## Next Steps
The following frontend tasks remain to be implemented:
- Task 22: Implement frontend project thumbnail upload component
- Task 22.1: Add thumbnail preview and management
- Task 22.2: Integrate thumbnail upload in project settings
- Task 22.3: Update project card to display thumbnails
- Task 22.4: Update project type definitions
## Related Files
- `backend/models/project.py` - Project model with thumbnail_path
- `backend/routers/projects.py` - Thumbnail upload/delete endpoints
- `backend/routers/files.py` - Thumbnail serving endpoint
- `backend/schemas/project.py` - Response schemas with thumbnail_url
- `backend/migrate_project_thumbnail.py` - Database migration script
- `backend/test_project_thumbnail.py` - Test script