From 64c561419113fc1d711abe170bae79a854cc6720 Mon Sep 17 00:00:00 2001 From: tuxarmy Date: Fri, 3 Apr 2026 12:03:40 +0700 Subject: [PATCH] docs: update README.md --- README.md | 228 ++++++------------ app/Providers/Filament/AdminPanelProvider.php | 2 + public/favicon.ico | Bin 0 -> 3109 bytes 3 files changed, 74 insertions(+), 156 deletions(-) diff --git a/README.md b/README.md index 3a0fc9f..0ad4d53 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,10 @@ Sistem web production-ready untuk **Organisasi Pemuda Desa Persegi**, berlokasi | Backend | Laravel 13 | | Admin Panel | Filament 5.x | | Authorization | Filament Shield + Spatie Permission | -| Database | MySQL | -| Frontend Publik | Blade | +| Database | MySQL / MariaDB | +| Frontend Publik | Blade + Tailwind CSS | | Realtime | Livewire | +| Queue | Supervisor | --- @@ -22,7 +23,7 @@ Sistem web production-ready untuk **Organisasi Pemuda Desa Persegi**, berlokasi ``` app/ ├── Filament/ -│ ├── Resources/ # Admin panel resources +│ ├── Resources/ │ │ ├── Activities/ # Manajemen kegiatan │ │ ├── Approvals/ # Multi-approval │ │ ├── Audits/ # Audit internal @@ -35,28 +36,21 @@ app/ │ │ └── Votes/ # Sistem voting │ └── Widgets/ │ ├── StatsOverview.php # Widget dashboard utama -│ ├── CashStatsWidget.php # Widget statistik kas (halaman transaksi) +│ ├── CashStatsWidget.php # Widget statistik kas │ └── ActivityLogWidget.php # Widget log aktivitas ├── Models/ -│ ├── User.php # Anggota / pengguna sistem -│ ├── Division.php # Divisi organisasi -│ ├── Activity.php # Kegiatan -│ ├── CashRecord.php # Transaksi kas -│ ├── CashCategory.php # Kategori kas (pemasukan/pengeluaran) -│ ├── Vote.php # Voting -│ ├── VoteItem.php # Pilihan suara per user -│ ├── Approval.php # Multi-approval -│ ├── ApprovalItem.php # Keputusan per approver -│ ├── Audit.php # Temuan audit -│ ├── AuditResponse.php # Respons atas temuan audit -│ ├── MemberStatusLog.php # Riwayat perubahan status anggota -│ ├── ActivityLog.php # Log global semua aksi -│ ├── Post.php # Artikel/berita publik -│ └── ContactMessage.php # Pesan kontak dari publik +│ ├── User.php, Division.php, Activity.php +│ ├── CashRecord.php, CashCategory.php +│ ├── Vote.php, VoteItem.php +│ ├── Approval.php, ApprovalItem.php +│ ├── Audit.php, AuditResponse.php +│ ├── MemberStatusLog.php, ActivityLog.php +│ ├── Post.php, ContactMessage.php └── Observers/ - ├── CashRecordObserver.php - ├── ActivityObserver.php - └── UserObserver.php + ├── CashRecordObserver.php # Log + threshold approval/voting + ├── ActivityObserver.php # Log approval & eksekusi kegiatan + ├── UserObserver.php # Log perubahan status anggota + └── VoteObserver.php # Notifikasi voting baru ke semua user ``` --- @@ -65,171 +59,66 @@ app/ | Role | Deskripsi | |---|---| -| `super_admin` | Full akses, bisa override semua, semua aksi di-log | +| `super_admin` | Full akses, override semua, semua aksi di-log | | `ketua` | Approval kegiatan, verifikasi kas, lihat semua data | | `bendahara` | Input & kelola transaksi kas | | `pengurus` | Submit kegiatan ke pending | -| `anggota` | Akses terbatas, lihat data sendiri | +| `anggota` | Akses terbatas, bisa voting | | `auditor` | Read-only + bisa buat temuan audit | --- -## Fitur & Use Case +## Fitur -### 1. Manajemen Anggota +### Keuangan (Kas) -**Aktor:** ketua, pengurus, super_admin +Threshold otomatis saat transaksi dibuat: -| Use Case | Deskripsi | +| Jumlah | Alur | |---|---| -| Tambah anggota | Input data: nama, telepon, alamat, divisi, status | -| Ubah status anggota | Aktif → Nonaktif wajib isi `inactive_reason` | -| Lihat riwayat status | Semua perubahan status tercatat di `member_status_logs` | -| Filter per divisi | Anggota bisa difilter berdasarkan divisi | +| < Rp 500.000 | Langsung bisa diverifikasi | +| Rp 500.000 – Rp 2.000.000 | Notifikasi ke ketua → perlu approval ketua | +| > Rp 2.000.000 | Voting dibuat otomatis → perlu mayoritas >50% | -**Business rule:** -- Hanya ketua, pengurus, super_admin yang bisa ubah status -- Setiap perubahan status otomatis dicatat ke `member_status_logs` via Observer +- Transaksi yang belum diverifikasi tidak masuk ke total kas +- Setelah `verified_at` terisi, data terkunci (tidak bisa diubah/dihapus) +- Widget statistik kas tampil di halaman transaksi: total saldo, pemasukan/pengeluaran bulan ini, saldo bulan lalu ---- +### Kegiatan -### 2. Struktur Organisasi (Divisi) - -**Aktor:** ketua, super_admin - -| Use Case | Deskripsi | -|---|---| -| Kelola divisi | CRUD divisi organisasi | -| Lihat anggota per divisi | Relasi one-to-many ke User | - ---- - -### 3. Kegiatan - -**Aktor:** pengurus (buat), ketua (approve), semua (lihat) - -| Use Case | Deskripsi | -|---|---| -| Buat kegiatan | Status awal: `draft` | -| Submit ke review | `draft` → `pending` (oleh pengurus) | -| Approve/Tolak | `pending` → `approved` / `rejected` (oleh ketua) | -| Tandai selesai | Wajib isi `executed_at` + `execution_notes` | -| Kelola peserta | Many-to-many anggota ↔ kegiatan | - -**Workflow status:** ``` draft → pending → approved → (executed_at diisi) → rejected ``` ---- +### Voting -### 4. Keuangan (Kas) +- Semua user bisa melihat dan memberi suara +- Tipe: `activity`, `finance`, `general` +- Notifikasi ke semua user saat voting baru dibuat +- Mayoritas >50% untuk lolos -**Aktor:** bendahara (input), ketua & super_admin (verifikasi & lihat) +### Notifikasi -| Use Case | Deskripsi | -|---|---| -| Input transaksi | Bendahara input pemasukan/pengeluaran | -| Verifikasi transaksi | Ketua/super_admin verifikasi, setelah itu data terkunci | -| Lihat statistik kas | Widget di halaman transaksi: total saldo, pemasukan/pengeluaran bulan ini, saldo bulan lalu | -| Filter transaksi | Filter per kategori, tanggal, status verifikasi | +- Database notifications via Filament +- Polling otomatis setiap 30 detik +- Queue diproses via Supervisor -**Business rule:** -- Setelah `verified_at` terisi, data tidak bisa diubah/dihapus -- Threshold keuangan: - - < Rp 500.000 → bendahara saja - - Rp 500.000 – Rp 2.000.000 → butuh persetujuan ketua - - > Rp 2.000.000 → multi-approval atau voting +### Konten Publik ---- - -### 5. Voting - -**Aktor:** semua role (sesuai permission) - -| Use Case | Deskripsi | -|---|---| -| Buat voting | Tipe: `activity`, `finance`, `general` | -| Beri suara | Pilihan: `approve`, `reject`, `abstain` | -| Tutup voting | Status: `open` → `closed` | -| Lihat hasil | Mayoritas >50% untuk lolos | - ---- - -### 6. Multi-Approval - -**Aktor:** role yang ditentukan per approval - -| Use Case | Deskripsi | -|---|---| -| Buat approval | Tentukan jumlah approval yang dibutuhkan | -| Beri keputusan | Tiap approver bisa approve/reject + catatan | -| Cek status | Lolos jika jumlah approve terpenuhi | - ---- - -### 7. Audit Internal - -**Aktor:** auditor (buat temuan), pengurus/ketua (respons) - -| Use Case | Deskripsi | -|---|---| -| Buat temuan | Tipe: `warning` / `critical`, bisa terkait model apapun | -| Respons temuan | Pihak terkait bisa balas temuan audit | -| Pantau status | Auditor bisa track status penyelesaian | - ---- - -### 8. Konten Publik - -**Aktor:** pengurus, ketua, super_admin - -| Use Case | Deskripsi | -|---|---| -| Buat artikel/berita | Post dengan status `draft` / `published` | -| Website publik | Halaman publik berbasis Blade untuk masyarakat | -| Pesan kontak | Masyarakat bisa kirim pesan, admin bisa lihat & balas | - ---- - -### 9. Dashboard - -Widget yang tampil di halaman utama admin: - -| Widget | Isi | -|---|---| -| StatsOverview | Anggota aktif, total kas, kegiatan berjalan, kegiatan pending | -| ActivityLogWidget | Log aktivitas terbaru di sistem | - -Widget khusus halaman transaksi: - -| Widget | Isi | -|---|---| -| CashStatsWidget | Total saldo, pemasukan bulan ini, pengeluaran bulan ini, saldo bulan lalu | +- Website publik berbasis Blade (font: Roboto + Playfair Display) +- Artikel/berita, halaman kegiatan, form kontak +- Link ke website publik tersedia di sidebar admin --- ## Log & Audit Trail -Semua aksi penting otomatis dicatat via Observer: - | Event | Dicatat di | |---|---| | Perubahan status anggota | `member_status_logs` | -| Transaksi kas baru | `activity_logs` | -| Verifikasi kas | `activity_logs` | -| Approval kegiatan | `activity_logs` | -| Eksekusi kegiatan | `activity_logs` | - ---- - -## Keamanan - -- Setiap resource dilindungi Laravel Policy -- Permission granular dikelola via Filament Shield -- Fitur impersonate: super_admin bisa login sebagai user lain (untuk debugging/support) -- Input divalidasi di semua form +| Transaksi kas baru/verifikasi | `activity_logs` | +| Approval/eksekusi kegiatan | `activity_logs` | --- @@ -240,8 +129,35 @@ composer install cp .env.example .env php artisan key:generate php artisan migrate --seed -php artisan shield:generate --all +php artisan shield:generate --panel=admin php artisan shield:super-admin --user=1 ``` Akses admin panel: `/dashboard` + +### Queue Worker (Supervisor) + +```ini +[program:persegi-worker] +command=php /path/to/project/artisan queue:work --sleep=3 --tries=3 +autostart=true +autorestart=true +user=$USER +redirect_stderr=true +stdout_logfile=/var/log/persegi-worker.log +``` + +```bash +sudo supervisorctl reread +sudo supervisorctl update +sudo supervisorctl start persegi-worker +``` + +### Production + +```bash +php artisan config:cache +php artisan route:cache +php artisan view:cache +php artisan permission:cache-reset +``` diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index a6cb435..887968e 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -33,6 +33,8 @@ class AdminPanelProvider extends PanelProvider ->colors([ 'primary' => Color::Amber, ]) + ->resourceCreatePageRedirect('index') + ->resourceEditPageRedirect('index') ->databaseNotifications() ->databaseNotificationsPolling('30s') ->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources') diff --git a/public/favicon.ico b/public/favicon.ico index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..369ba8d7ff1f9290d8f38c3b041ba080c488acdb 100644 GIT binary patch literal 3109 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 literal 0 HcmV?d00001