222 lines
6.2 KiB
Markdown
222 lines
6.2 KiB
Markdown
# 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
|