init push
This commit is contained in:
207
docs/file-manager-preview.md
Normal file
207
docs/file-manager-preview.md
Normal file
@@ -0,0 +1,207 @@
|
||||
# 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` |
|
||||
Reference in New Issue
Block a user