# 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
