208 lines
5.9 KiB
Markdown
208 lines
5.9 KiB
Markdown
# 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` |
|