240 lines
4.8 KiB
Markdown
240 lines
4.8 KiB
Markdown
# Client Logo Upload API Documentation
|
|
|
|
## Overview
|
|
|
|
API untuk mengelola logo client dengan integrasi MinIO storage. Mendukung upload, delete, dan generate presigned URL untuk logo client.
|
|
|
|
## Endpoints
|
|
|
|
### 1. Upload Client Logo
|
|
|
|
**POST** `/clients/logo`
|
|
|
|
Upload logo image untuk client yang sedang login (menggunakan client ID dari auth token).
|
|
|
|
#### Request
|
|
- **Content-Type**: `multipart/form-data`
|
|
- **Parameter**:
|
|
- `logo` (form-data): File image (jpg, jpeg, png, gif, webp, max 5MB)
|
|
- **Headers**:
|
|
- `Authorization`: Bearer token (required)
|
|
|
|
#### Response
|
|
```json
|
|
{
|
|
"success": true,
|
|
"messages": ["Client logo uploaded successfully"],
|
|
"data": {
|
|
"imagePath": "clients/logos/{clientId}/filename_timestamp_random.ext"
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Example cURL
|
|
```bash
|
|
curl -X POST \
|
|
http://localhost:8080/clients/logo \
|
|
-H "Authorization: Bearer your-token" \
|
|
-F "logo=@/path/to/logo.png"
|
|
```
|
|
|
|
### 2. Delete Client Logo
|
|
|
|
**DELETE** `/clients/{id}/logo`
|
|
|
|
Hapus logo client dari MinIO dan database.
|
|
|
|
#### Request
|
|
- **Parameter**:
|
|
- `id` (path): Client ID (UUID)
|
|
|
|
#### Response
|
|
```json
|
|
{
|
|
"success": true,
|
|
"messages": ["Client logo deleted successfully"]
|
|
}
|
|
```
|
|
|
|
#### Example cURL
|
|
```bash
|
|
curl -X DELETE \
|
|
http://localhost:8080/clients/123e4567-e89b-12d3-a456-426614174000/logo \
|
|
-H "Authorization: Bearer your-token"
|
|
```
|
|
|
|
### 3. Get Logo URL
|
|
|
|
**GET** `/clients/{id}/logo/url`
|
|
|
|
Generate presigned URL untuk mengakses logo client (valid 24 jam).
|
|
|
|
#### Request
|
|
- **Parameter**:
|
|
- `id` (path): Client ID (UUID)
|
|
|
|
#### Response
|
|
```json
|
|
{
|
|
"success": true,
|
|
"messages": ["Logo URL generated successfully"],
|
|
"data": {
|
|
"url": "https://minio.example.com/bucket/clients/logos/{clientId}/filename?X-Amz-Algorithm=..."
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Example cURL
|
|
```bash
|
|
curl -X GET \
|
|
http://localhost:8080/clients/123e4567-e89b-12d3-a456-426614174000/logo/url \
|
|
-H "Authorization: Bearer your-token"
|
|
```
|
|
|
|
## File Validation
|
|
|
|
### Supported Formats
|
|
- JPEG (.jpg, .jpeg)
|
|
- PNG (.png)
|
|
- GIF (.gif)
|
|
- WebP (.webp)
|
|
|
|
### File Size Limit
|
|
- Maximum: 5MB
|
|
|
|
### File Naming
|
|
Uploaded files akan di-rename dengan format:
|
|
```
|
|
{original_name}_{timestamp}_{random_number}.{extension}
|
|
```
|
|
|
|
Example: `company_logo_1640995200_123456.png`
|
|
|
|
## Storage Structure
|
|
|
|
Logo disimpan di MinIO dengan struktur path:
|
|
```
|
|
clients/logos/{clientId}/{filename}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
### Common Errors
|
|
|
|
#### 400 Bad Request
|
|
```json
|
|
{
|
|
"success": false,
|
|
"messages": ["Invalid file type. Only jpg, jpeg, png, gif, webp are allowed"]
|
|
}
|
|
```
|
|
|
|
#### 413 Payload Too Large
|
|
```json
|
|
{
|
|
"success": false,
|
|
"messages": ["File size too large. Maximum size is 5MB"]
|
|
}
|
|
```
|
|
|
|
#### 404 Not Found
|
|
```json
|
|
{
|
|
"success": false,
|
|
"messages": ["Client not found"]
|
|
}
|
|
```
|
|
|
|
#### 500 Internal Server Error
|
|
```json
|
|
{
|
|
"success": false,
|
|
"messages": ["Failed to upload file to MinIO"]
|
|
}
|
|
```
|
|
|
|
## Database Schema
|
|
|
|
### New Fields Added to `clients` Table
|
|
|
|
```sql
|
|
ALTER TABLE clients
|
|
ADD COLUMN logo_url VARCHAR(255), -- External logo URL
|
|
ADD COLUMN logo_image_path VARCHAR(255), -- MinIO storage path
|
|
ADD COLUMN address TEXT, -- Physical address
|
|
ADD COLUMN phone_number VARCHAR(50), -- Contact phone
|
|
ADD COLUMN website VARCHAR(255); -- Official website
|
|
```
|
|
|
|
## Usage Examples
|
|
|
|
### Frontend Integration
|
|
|
|
#### Upload Logo
|
|
```javascript
|
|
const uploadLogo = async (clientId, file) => {
|
|
const formData = new FormData();
|
|
formData.append('logo', file);
|
|
|
|
const response = await fetch(`/clients/${clientId}/logo`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${token}`
|
|
},
|
|
body: formData
|
|
});
|
|
|
|
return response.json();
|
|
};
|
|
```
|
|
|
|
#### Get Logo URL
|
|
```javascript
|
|
const getLogoUrl = async (clientId) => {
|
|
const response = await fetch(`/clients/${clientId}/logo/url`, {
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': `Bearer ${token}`
|
|
}
|
|
});
|
|
|
|
const result = await response.json();
|
|
return result.data.url;
|
|
};
|
|
```
|
|
|
|
### Backend Integration
|
|
|
|
#### Update Client with Logo Path
|
|
```go
|
|
updateReq := request.ClientsUpdateRequest{
|
|
LogoImagePath: &imagePath,
|
|
// other fields...
|
|
}
|
|
|
|
err := clientsService.Update(clientId, updateReq)
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **Authentication**: Semua endpoint memerlukan Bearer token
|
|
2. **File Validation**: Validasi format dan ukuran file
|
|
3. **Presigned URLs**: URL hanya valid 24 jam
|
|
4. **Cleanup**: File lama otomatis dihapus saat upload baru
|
|
|
|
## Performance Notes
|
|
|
|
1. **File Size**: Batasi ukuran file untuk performa optimal
|
|
2. **CDN**: Pertimbangkan menggunakan CDN untuk distribusi logo
|
|
3. **Caching**: Cache presigned URLs di frontend
|
|
4. **Indexing**: Database indexes untuk query yang efisien
|
|
|
|
## Migration
|
|
|
|
Jalankan migration untuk menambahkan kolom baru:
|
|
|
|
```sql
|
|
-- File: docs/migrations/002_add_client_tenant_fields.sql
|
|
\i docs/migrations/002_add_client_tenant_fields.sql
|
|
```
|