# File Upload Feature Documentation

## Overview
The file upload feature allows authenticated users to upload images to the system. Images are automatically processed, compressed, and converted to JPEG format for optimal web performance.

## Components

### 1. Upload Middleware (`src/middleware/upload.js`)
- Configures Multer for handling multipart/form-data
- Implements file type validation (JPEG, PNG, GIF, WebP only)
- Enforces file size limits (5MB default)
- Generates unique filenames using UUID and timestamp
- Creates upload directory if it doesn't exist

### 2. Upload Controller (`src/controllers/uploadController.js`)
- Handles image upload requests
- Processes images using Sharp library:
  - Resizes to max 1200x1200 pixels (maintains aspect ratio)
  - Converts to JPEG format with 85% quality
  - Uses progressive JPEG encoding
- Cleans up original files after processing
- Returns image URL and metadata

### 3. Upload Routes (`src/routes/uploadRoutes.js`)
- POST `/api/v1/upload/image` - Upload and process an image
- Requires authentication (JWT token)
- Accepts single file with field name 'image'

### 4. Static File Serving
- Uploaded files are served from `/uploads` endpoint
- Configured in `app.js` using Express static middleware

## API Endpoint

### POST /api/v1/upload/image

**Authentication:** Required (Bearer token)

**Request:**
- Content-Type: multipart/form-data
- Field name: `image`
- Accepted formats: JPEG, PNG, GIF, WebP
- Max file size: 5MB (configurable via `MAX_FILE_SIZE` env variable)

**Success Response (200):**
```json
{
  "success": true,
  "data": {
    "url": "/uploads/uuid-timestamp.jpg",
    "filename": "uuid-timestamp.jpg",
    "originalName": "original-filename.png",
    "size": 12345
  }
}
```

**Error Responses:**

- **401 Unauthorized** - Missing or invalid authentication token
- **400 Bad Request** - No file uploaded
  ```json
  {
    "success": false,
    "error": {
      "code": "NO_FILE",
      "message": "No file uploaded"
    }
  }
  ```
- **500 Internal Server Error** - Invalid file type or processing error

## Configuration

### Environment Variables

```env
# Upload directory path (relative or absolute)
UPLOAD_PATH=./uploads

# Maximum file size in bytes (default: 5MB)
MAX_FILE_SIZE=5242880
```

### File Processing Settings

Located in `src/controllers/uploadController.js`:
- Max dimensions: 1200x1200 pixels
- JPEG quality: 85%
- Progressive encoding: enabled
- Fit mode: inside (maintains aspect ratio, no enlargement)

## Security Features

1. **Authentication Required** - All upload requests must include valid JWT token
2. **File Type Validation** - Only image files (JPEG, PNG, GIF, WebP) are accepted
3. **File Size Limits** - Configurable maximum file size (default 5MB)
4. **Unique Filenames** - UUID-based naming prevents overwrites and conflicts
5. **Input Sanitization** - File extensions and paths are validated

## Image Processing

### Automatic Optimizations
- **Resizing**: Images larger than 1200x1200 are automatically resized
- **Format Conversion**: All images are converted to JPEG for consistency
- **Compression**: 85% quality JPEG compression reduces file size
- **Progressive Loading**: Progressive JPEG encoding improves perceived load time

### Processing Flow
1. File uploaded via Multer middleware
2. Original file saved to upload directory
3. Sharp processes the image:
   - Resize if needed
   - Convert to JPEG
   - Apply compression
4. Processed file saved with .jpg extension
5. Original file deleted (if different from processed)
6. URL returned to client

## Usage Examples

### JavaScript/Fetch
```javascript
const formData = new FormData();
formData.append('image', fileInput.files[0]);

const response = await fetch('http://localhost:3000/api/v1/upload/image', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`
  },
  body: formData
});

const result = await response.json();
console.log('Image URL:', result.data.url);
```

### cURL
```bash
curl -X POST http://localhost:3000/api/v1/upload/image \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -F "image=@/path/to/image.jpg"
```

### Axios
```javascript
const formData = new FormData();
formData.append('image', file);

const response = await axios.post('/api/v1/upload/image', formData, {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'multipart/form-data'
  }
});

console.log('Image URL:', response.data.data.url);
```

## Testing

### Unit Tests
Located in `src/tests/upload.test.js`:
- Authentication validation
- Middleware configuration
- Controller exports

### Manual Testing
See `src/tests/upload-manual-test.md` for detailed manual testing guide.

## Requirements Validation

This implementation satisfies the following requirements:

**Requirement 2.2**: Service creation requires image field
- Provides image upload endpoint for service images
- Validates and processes uploaded images

**Requirement 5.2**: Withdrawal supports payment methods with details
- Can be used to upload payment method verification documents
- Supports various image formats for payment receipts

## File Structure

```
backend/
├── src/
│   ├── middleware/
│   │   └── upload.js          # Multer configuration
│   ├── controllers/
│   │   └── uploadController.js # Upload handling logic
│   ├── routes/
│   │   └── uploadRoutes.js     # Upload API routes
│   ├── tests/
│   │   ├── upload.test.js      # Unit tests
│   │   └── upload-manual-test.md # Manual testing guide
│   └── app.js                  # Route integration
├── uploads/                    # Upload directory (created automatically)
└── UPLOAD_FEATURE.md          # This documentation
```

## Maintenance Notes

### Cleanup
- Uploaded files are not automatically deleted
- Consider implementing a cleanup job for old/unused files
- Monitor disk space usage in production

### Scaling Considerations
- For high-traffic applications, consider using cloud storage (S3, GCS)
- Implement CDN for serving uploaded images
- Add image caching headers for better performance

### Future Enhancements
- Multiple file upload support
- Image cropping/editing capabilities
- Thumbnail generation
- Different size variants (small, medium, large)
- Image metadata extraction (EXIF data)
- Virus scanning for uploaded files
