Filament Curator
Starter kit ini memakai Filament Curator sebagai final media library di panel Filament.
Dokumen ini menjelaskan posisi Curator di arsitektur project, konfigurasi storage yang dipakai sekarang, dan pola integrasi yang sudah disiapkan agar tetap nyaman dipakai ulang.
Ringkasan Arsitektur
Arsitektur media di starter kit ini sekarang dibagi menjadi dua lapisan:
curatoruntuk final media libraryuploadsuntuk temporary upload lifecycle API mobile di tahap berikutnya
Artinya:
- Filament memakai Curator sebagai media manager dan media picker
- file final yang dipakai model domain disimpan sebagai record di tabel
curator - upload temporary mobile nantinya tidak langsung masuk ke tabel
curator
Posisi Curator Saat Ini
Curator dipakai sebagai:
- media manager resmi di Filament
- final source of truth untuk media yang sudah sah dipakai aplikasi
- picker untuk field yang memang perlu memilih media existing
- target akhir untuk upload langsung dari Filament
Curator bukan pengganti flow upload API mobile berbasis signed upload. Untuk mobile, file temporary tetap direncanakan lewat tabel uploads, lalu hasil final akan dibuat menjadi record Curator.
Storage Strategy
Starter kit ini sengaja dibuat sederhana:
- developer cukup memilih backend storage utama:
localataus3 - Curator mengikuti disk default aktif dari konfigurasi
- visibility default Curator tetap
private - field tertentu boleh override visibility jika memang harus
public
Konfigurasi utamanya ada di config/curator.php.
Default-nya sekarang:
CURATOR_DEFAULT_DISKmengikutiFILAMENT_FILESYSTEM_DISKatauFILESYSTEM_DISKCURATOR_DEFAULT_VISIBILITY=private
Jadi mental model-nya:
local= media final tetap bisa private dan dilayani via temporary URLs3= media final bisa private atau public sesuai visibility record
Ownership & Privacy (Blameable)
Starter kit ini telah meningkatkan fitur Curator dengan sistem kepemilikan dan privasi yang lebih eksplisit:
- Created By: Setiap media yang diunggah kini mencatat siapa pembuatnya melalui kolom
created_by. - Privacy Level: Setiap media memiliki status privasi (
PRIVATE,MEMBER, atauPUBLIC) yang menentukan siapa yang dapat melihat media tersebut. - Security Policy: Hanya
creator,admin, dansuper_adminyang memiliki akses penuh untuk mengedit atau menghapus media.
Penjelasan mendalam mengenai fitur ini dapat dilihat di docs/13-curator-privacy-and-tracking.md.
Dedicated Temporary Upload Disk
Untuk upload Filament dan Curator, temporary upload Livewire sekarang memakai disk terpisah.
Konfigurasi ini ada di config/livewire.php.
Disk temporary terpisah ini penting karena Curator membaca metadata dari file temporary setelah file dipindahkan ke lokasi final. Kalau temporary upload dan final media memakai root filesystem yang sama, metadata file temporary bisa hilang lebih dulu dan upload gagal.
Karena itu starter kit sekarang memakai:
- disk temporary upload khusus
uploads_tmp - disk final media mengikuti Curator default disk
Ini berlaku baik untuk local maupun s3 sebagai storage final.
Mixed Visibility: Private by Default, Public by Exception
Secara default, media Curator tetap dianggap private.
Ini keputusan yang disengaja supaya:
- dokumen atau media sensitif tidak otomatis terbuka
- starter kit aman untuk kebutuhan jangka panjang
- public media hanya dibuka jika memang jelas dibutuhkan
Saat ini pengecualiannya adalah field yang memang wajar public, misalnya avatar user. Untuk kasus seperti itu, field dapat override visibility langsung di komponen upload tanpa mengubah default global Curator.
Untuk API mobile nantinya, client juga boleh mengirim requested_visibility, tetapi backend tetap harus memutuskan final_visibility berdasarkan purpose, permission, dan policy server.
Model Curator Kustom
Starter kit mengarahkan model Curator ke app/Models/CuratorMedia.php.
Model ini dipakai supaya URL turunan media tetap konsisten untuk setup mixed visibility. Pendekatan ini lebih aman dibanding mengandalkan asumsi satu source image global ketika project mulai memiliki campuran media public dan private.
Integrasi Domain Saat Ini
Field domain yang saat ini sudah terhubung ke Curator:
users.avatar_curator_idposts.thumbnail_curator_id
Relasi model yang dipakai:
- user ->
avatarMedia - post ->
thumbnailCurator
Dengan pola ini, model domain tidak menyimpan path file mentah sebagai source of truth utama. Yang disimpan adalah referensi ke record Curator.
Avatar User: Direct Upload Tanpa Picker
Avatar user sekarang tidak lagi memakai CuratorPicker seperti thumbnail post.
Sebagai gantinya, avatar memakai komponen reusable app/Filament/Forms/Components/CuratorFileUpload.php.
Tujuan pola ini:
- user bisa upload avatar langsung tanpa harus membuka media manager dulu
- hasil upload tetap otomatis masuk ke tabel
curator - field model tetap menyimpan
avatar_curator_id - pengalaman upload terasa seperti avatar uploader biasa, bukan picker media generik
Pemakaiannya saat ini ada di:
CuratorFileUpload
CuratorFileUpload adalah komponen reusable berbasis FileUpload yang dibuat untuk kasus upload langsung tetapi final result-nya tetap record Curator.
Komponen ini sekarang menangani sendiri hal-hal berikut:
- hydrate preview dari
curator_idyang sudah ada - upload file baru lewat perilaku native
FileUpload - saat save, otomatis membuat atau memperbarui record Curator
- mengembalikan state final berupa
curator_id
Prinsip API komponen ini sekarang dibuat konsisten:
- kalau sudah ada default bawaan
FileUpload, gunakan default itu - override cukup lewat method standar seperti
disk(),directory(),visibility(),acceptedFileTypes(),maxSize(), dan lain-lain - jangan menambahkan helper alias yang membuat API terasa berbeda tanpa alasan kuat
Contoh pemakaian:
CuratorFileUpload::make('avatar_curator_id')
->relationship('avatarMedia', 'id')
->avatar()
->imageEditor()
->directory('avatars')
->visibility('public');
Thumbnail Post: Tetap Picker
Untuk thumbnail post, starter kit saat ini masih memakai CuratorPicker di app/Filament/Resources/Posts/Schemas/PostForm.php.
Itu masih cocok karena kebutuhan thumbnail post lebih dekat ke media picker/editorial flow:
- bisa upload media baru dari Curator
- bisa memilih media existing
- tetap menyimpan
thumbnail_curator_id
Jadi sekarang ada dua pola resmi yang sama-sama valid:
CuratorFileUploaduntuk direct upload yang hasil akhirnya otomatis menjadi record CuratorCuratorPickeruntuk browse dan pick media existing dari Curator
Public dan Private di local dan s3
Cara berpikir yang dipakai di starter kit ini:
Jika storage final adalah local
- media private dilayani dengan
temporaryUrl()atau route signed yang setara - media public tetap bisa diakses langsung jika field memang diarahkan ke visibility public
Jika storage final adalah s3
- media
publicmenggunakan URL biasa - media
privatemenggunakan signed URL / temporary URL
Jadi visibility tetap penting walaupun backend storage hanya dipilih dari local atau s3.
Arah Pengembangan Berikutnya
Tahap berikut yang sudah direncanakan adalah upload API mobile dengan tabel uploads.
Pola yang akan dipakai:
- mobile upload baru -> pegang
upload_id - endpoint domain menerima
*_upload_idatau*_curator_id - backend otomatis resolve hasil akhir ke record Curator
prepare uploadakan membaca rule perpurpose- client boleh mengusulkan visibility, tetapi server menetapkan hasil akhirnya
Dengan pola itu:
- mobile tidak perlu membuat record Curator secara manual sebelum submit form domain
- Filament dan mobile tetap bermuara ke final media library yang sama, yaitu
curator
Kesimpulan
Arah starter kit ini sekarang adalah:
- Curator menjadi final media library tunggal
- default media tetap
private - field tertentu seperti avatar boleh override menjadi
public - avatar memakai direct upload yang otomatis terhubung ke Curator
- field lain yang cocok untuk picker tetap bisa memakai
CuratorPicker - API mobile nanti dibangun di atas
uploads -> curator, bukan sistem media yang terpisah