Overview
ProjectFlow adalah aplikasi manajemen proyek dan tiket fullstack yang dibangun untuk membantu tim engineering dan project manager mengelola pekerjaan secara terstruktur. Sistem ini mendukung alur kerja lengkap dari perencanaan hingga penyelesaian proyek—mulai dari pembuatan proyek, pengelompokan tugas ke dalam epics, pelacakan tiket dengan status kustom, hingga pemantauan progres secara real-time. Dibangun di atas admin panel Filament dengan Livewire untuk interaktivitas tanpa reload, aplikasi ini menyediakan UI yang kaya fitur sekaligus performa tinggi berkat Laravel Octane (FrankenPHP). Sistem ini juga mendukung akses eksternal berbasis token untuk klien, sehingga klien dapat melihat progres proyek tanpa perlu akun internal.
Key Features
- Manajemen Proyek — Buat proyek dengan color-coding, pin project penting, timeline (start & end date), dan arsip proyek selesai
- Sistem Tiket — Tiket dengan status kustom (Kanban-style), prioritas berwarna (Low/Medium/High/Critical), multi-assignee, dan estimasi jam
- Epic Management — Kelompokkan tiket ke dalam epics dengan drag-and-drop sort order
- Gantt Timeline — Visualisasi jadwal tiket dalam format Gantt chart, dapat diekspor ke Excel
- Export & Import Tiket — Import tiket via CSV/XLSX template, export ke Excel
- Komentar Tiket — Rich text editor, internal/external comment, email notification
- Ticket History — Audit trail otomatis setiap perubahan status tiket
- External Access — Shared link berbasis token untuk akses klien tanpa login internal
- Role-Based Access Control — Multi-role (admin, member, viewer) dengan permission granular via Filament Shield
- Google OAuth — Login menggunakan akun Google
- Notifikasi — Real-time notification dalam app + email saat diassign ke proyek/tiket
- Project Notes — Catatan internal per proyek (private/public)
- Dashboard & Widget — Statistik proyek aktif, tiket overdue, progres tim
Challenges
- Manajemen permission yang kompleks — Setiap resource (proyek, tiket, komentar) memerlukan kebijakan akses yang berbeda tergantung role pengguna dan kepemilikan data.
- External client access tanpa autentikasi penuh — Klien perlu melihat progres proyek tanpa memiliki akun internal, tetapi akses tetap harus aman dan terbatas scope-nya.
- Performa query pada relasi bertingkat — Tiket memiliki banyak relasi (project, epic, status, priority, users, comments, history), berpotensi menyebabkan N+1 query pada list view.
- Gantt timeline export — Menghasilkan file Excel dengan layout Gantt yang benar memerlukan manipulasi sel, merge, dan styling programatik via PhpSpreadsheet.
- Multi-assignee pada tiket — Satu tiket dapat dikerjakan oleh beberapa orang sekaligus, memerlukan relasi many-to-many dengan tracking waktu assignment.
Solutions
- Filament Shield + Spatie Permission — Menggunakan policy-based authorization yang dikombinasikan dengan Filament Shield untuk generate permission per resource secara otomatis, lalu mengontrolnya dari UI admin.
- Token-based external access — Membuat tabel external_access dengan token unik dan expiry date. Livewire component ExternalDashboard menangani sesi klien tanpa menyentuh sistem auth utama.
- Eager loading + Performance indexes — Menambahkan migration khusus (add_performance_indexes) untuk index pada kolom yang sering difilter (project_id, status_id, priority_id) dan menggunakan with() secara konsisten di semua query list
- Custom Maatwebsite Excel export class — Membuat TicketsTimelineGantt export class yang mengatur posisi kolom, warna cell, dan header timeline secara dinamis sesuai rentang tanggal tiket.
- Pivot table ticket_users — Relasi many-to-many dengan pivot yang menyimpan assigned_at dan created_by, memungkinkan tracking siapa yang mengassign dan kapan.
Lessons Learned
- Filament 4 sangat fleksibel untuk membangun admin panel kompleks dengan cepat, tetapi customisasi di luar pola standar (seperti Livewire custom page) memerlukan pemahaman mendalam tentang lifecycle component-nya.
- Database index adalah investasi wajib sejak awal — query yang terasa cepat di data kecil bisa collapse di production dengan ribuan tiket.
- Pisahkan akses internal dan eksternal sejak arsitektur awal — menambahkan external access di tengah pengembangan memaksa refactor pada middleware dan route guard yang sudah ada.
- Event-driven notification membuat kode lebih bersih — menggunakan Laravel Events + Listeners alih-alih memanggil notifikasi langsung di controller membuat logika lebih mudah di-maintain dan di-test.
- Docker dari awal menghemat banyak waktu — environment yang konsisten antara development dan production menghilangkan masalah "works on my machine" terutama saat mengintegrasikan Octane dengan FrankenPHP.