# File Manager — Document Preview

Fitur ini memungkinkan FE untuk menampilkan preview dokumen (PDF, DOCX, XLSX, PPTX) secara inline tanpa user perlu mendownload file terlebih dahulu.

---

## Cara Kerja

### Untuk File PDF

PDF langsung dapat dirender oleh browser. Backend mengembalikan `preview_url` yang menunjuk ke file aslinya (sama dengan `download_url`). Tidak ada proses konversi.

### Untuk File Office (DOCX, XLSX, PPTX, DOC, XLS, PPT)

Dokumen dikonversi ke PDF secara otomatis oleh background worker saat file selesai diupload. Proses ini menggunakan **Gotenberg** (container yang menjalankan LibreOffice secara headless). Hasil konversi disimpan di S3 sebagai file terpisah (`.preview.pdf`).

### Untuk File Lainnya (Image, Video, dll)

`preview_url` tidak diisi (kosong). FE menangani preview image menggunakan `download_url` seperti sebelumnya.

---

## Flow Lengkap

```
1. FE upload file (existing flow — tidak berubah)

2. Background worker memproses file:
   - Image  → generate thumbnail (existing)
   - PDF    → tidak perlu konversi, preview_url = original URL
   - Office → konversi ke PDF via Gotenberg → simpan preview di S3 → update DB

3. File status menjadi "ready"

4. FE ambil detail file:
   GET /api/v1/file-manager/files/get/{uuid}
   → response berisi preview_url

5. FE render preview_url di iframe/tab baru
```

---

## Endpoint

### GET /api/v1/file-manager/files/get/{uuid}

Endpoint existing. Response sekarang memiliki field tambahan `preview_url` di dalam `attributes`.

#### Contoh Response (PDF atau Office doc yang sudah diproses)

```json
{
  "data": {
    "type": "file_manager_file",
    "id": "019d8215-c622-7576-86bd-3ddeecaf4867",
    "attributes": {
      "name": "laporan.docx",
      "extension": "docx",
      "size_bytes": 204800,
      "mime_type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      "status": "ready",
      "download_url": "https://s3.../laporan.docx?X-Amz-Signature=...",
      "preview_url": "https://s3.../laporan.preview.pdf?X-Amz-Signature=...",
      "audit": {
        "created_at": "2026-07-06T10:00:00Z",
        "updated_at": "2026-07-06T10:00:05Z"
      }
    }
  }
}
```

#### Contoh Response (file masih diproses atau konversi gagal)

```json
{
  "data": {
    "type": "file_manager_file",
    "id": "019d8215-c622-7576-86bd-3ddeecaf4867",
    "attributes": {
      "name": "laporan.docx",
      "status": "processing",
      "download_url": "https://s3.../laporan.docx?X-Amz-Signature=...",
      "preview_url": ""
    }
  }
}
```

---

## Logika `preview_url` di Backend

| Kondisi | `preview_url` |
|---------|--------------|
| File PDF | Sama dengan `download_url` |
| File Office, sudah dikonversi | Presigned URL ke `.preview.pdf` di S3 |
| File Office, belum/gagal dikonversi | Kosong (`""`) |
| File image / tipe lainnya | Kosong (`""`) |

---

## Error Handling

Jika konversi via Gotenberg gagal:

- **Error 4xx dari Gotenberg** (dokumen tidak valid/tidak didukung): file status menjadi `failed`. FE harus handle kondisi ini dengan menampilkan pesan error atau fallback ke tombol download.
- **Error jaringan atau 5xx dari Gotenberg** (Gotenberg sedang down): worker akan retry otomatis. File status tetap `processing` sampai berhasil atau melebihi batas retry.

---

## Panduan untuk FE

```js
const file = await api.getFile(uuid)
const { preview_url, download_url, status, mime_type } = file.data.attributes

if (preview_url) {
  // Render preview di iframe
  openPreviewModal(preview_url)
} else if (status === 'processing') {
  // Tampilkan loading / tunggu SSE event
  showProcessingIndicator()
} else if (status === 'failed') {
  // Tampilkan error, tawarkan download langsung
  showError('Preview tidak tersedia')
  offerDownload(download_url)
} else {
  // File type tidak didukung preview (video, archive, dll)
  offerDownload(download_url)
}
```

---

## Cara Test di Local (Tanpa Frontend)

### Prasyarat

1. Gotenberg harus jalan:
   ```bash
   docker-compose up gotenberg
   ```

2. File worker harus jalan:
   ```bash
   docker-compose up file-worker
   ```

3. Pastikan `.env.local` sudah ada `GOTENBERG_URL=http://localhost:3000`

### Langkah Test

```bash
# 1. Upload file DOCX (step upload + create seperti biasa)

# 2. Tunggu file status menjadi "ready" (cek via SSE atau polling GET)

# 3. Ambil detail file
curl -H "Authorization: Bearer <token>" \
  http://localhost:8080/api/v1/file-manager/files/get/<uuid>

# 4. Salin nilai preview_url dari response

# 5. Buka preview_url di browser — PDF harus tampil
```

---

## Konfigurasi

### docker-compose.yml

```yaml
gotenberg:
  image: gotenberg/gotenberg:8
  ports:
    - "3000:3000"
  restart: unless-stopped
```

### .env.local

```bash
GOTENBERG_URL=http://localhost:3000        # local development
# GOTENBERG_URL=http://gotenberg:3000      # dalam docker-compose network
```

---

## File yang Diubah (OP-1273)

| File | Perubahan |
|------|-----------|
| `migrations/20260706_file_preview_metadata.sql` | ALTER TABLE tambah kolom `preview_*` |
| `docker-compose.yml` | Tambah service Gotenberg |
| `.env.local.example` | Tambah `GOTENBERG_URL` |
| `config/local/config.json` | Tambah section `gotenberg.url` |
| `internal/config/config.go` | Tambah struct `GotenbergConfig` |
| `internal/config/loader.go` | Mapping config Gotenberg |
| `internal/domain/file_manager/model_file.go` | Tambah field `Preview*` di struct `File` |
| `internal/service/file_processing_usecase.go` | Tambah fungsi `convertDocumentIfNeeded`, `callGotenberg`, helper |
| `cmd/worker/file_worker.go` | Wire up `GotenbergURL` ke use case |
| `internal/transport/http/dto/shared/file_manager_file_shared.go` | Tambah field `PreviewURL` di `FileManagerFileDetailAttributes` |
| `internal/transport/http/handlers/file_manager_request_helpers.go` | Tambah `PreviewURL` ke `fileManagerDownloadURLs` dan logic presign |
| `internal/transport/http/handlers/file_manager_file_handler.go` | Update `fileManagerFileDetailResource` untuk set `PreviewURL` |
