appointment_system/backend/UPLOAD_FEATURE.md
2025-12-11 22:50:18 +08:00

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