# 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
```
