init push

This commit is contained in:
2026-07-16 22:16:45 +07:00
commit 8b068bdb10
1021 changed files with 332816 additions and 0 deletions

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