# SUPERAPP ACADEMY V20.2 — PEMULIHAN WHOOPS KARENA CACHE CPANEL

Basis: Source V20.1 lengkap (CodeIgniter 4, PHP 8.2+). Paket ini memperbaiki kegagalan bootstrap ketika folder `writable/cache/` tidak bisa ditulis. Tidak memerlukan migrasi SQL baru dan tidak menghapus data.

## A. Penyebab yang terbukti dari log

```
CodeIgniter\Cache\Exceptions\CacheException:
Cache unable to write to ".../writable/cache/"
```

CacheFactory membuat FileHandler pada tahap inisialisasi framework, lalu constructor melempar exception ketika cache tidak bisa ditulis. `backupHandler = 'dummy'` pada konfigurasi lama tidak menyelamatkan error ini karena fallback CodeIgniter hanya terjadi pada handler yang tidak didukung/initialize tertentu, bukan exception pada constructor FileHandler.

## B. Perubahan V20.2

1. `app/Config/Cache.php`: cek folder sebelum handler dibuat. Buat direktori yang hilang (jika izin memungkinkan). Jika gagal, gunakan handler `dummy` secara aman agar BERANDA dan ADMIN tetap terbuka. Cache dummy tidak menyimpan data sementara antar-request, tidak menyentuh database/keranjang/session.
2. `app/Config/Logger.php`: saat `writable/logs/` gagal ditulis, kirim error ke PHP `error_log` (lihat cPanel Metrics → Errors) alih-alih menghilangkan log.
3. `app/Services/SecureUrlId.php`: membaca key existing dalam mode baca, tidak lagi memerlukan akses tulis untuk key yang sudah ada. Key baru tetap harus dibuat hanya sekali dan disimpan aman.
4. Paket ZIP memiliki placeholder terlindungi (`index.html`, `.htaccess`) untuk `writable/cache`, `logs`, `session`, `secure`, `uploads`, `debugbar`.
5. `/panel-admin/diagnostik`: status folder dan cache handler (hanya admin).
6. Page cache dibatasi untuk HTTP 200 untuk menghindari menyimpan halaman error.

## C. Cara TIMPA SEMUA aplikasi via cPanel

1. **WAJIB backup** DATABASE lewat phpMyAdmin, `.env` asli, `writable/uploads/`, `writable/secure/route-id.key` dan semua file upload `public/uploads/`.
2. Upload `SuperApp_Academy_V20_2_FULL_SOURCE_FIX_CACHE_LOG.zip` ke **root aplikasi CI4** (tempat `app/`, `public/`, `system/`, `writable/` berada), BUKAN ke `public/` saja.
3. Extract lalu overwrite semua berkas kode lama. ZIP sengaja **TIDAK MENYERTAKAN `.env`**, key, session aktif, data upload peserta atau log produksi.
4. Pastikan `writable/cache`, `writable/logs`, `writable/session`, dan `writable/secure` milik pengguna PHP dan bisa ditulis. Umumnya permission folder 0755 cukup ketika PHP/hosting menggunakan user yang sama; untuk shared group dapat diperlukan 0775 (jangan 0777). Jika ownership berbeda, minta hosting menyesuaikan.
5. Pastikan disk quota serta inode hosting masih tersisa. Bahkan folder 755 akan gagal ditulis bila quota habis.
6. Buka beranda dan `/panel-admin/diagnostik`. Bila handler cache `dummy`, website boleh hidup sementara, tetapi **ownership cache tetap wajib diperbaiki** agar caching kembali efisien.
7. Uji login Google, menu Materi/Kelas, katalog, bukti pembayaran, catatan admin, tiket, dan akses CAT di staging sebelum produksi.
8. Biarkan `.env` menggunakan `CI_ENVIRONMENT = production`. Hindari `app.displayErrors = true` di produksi.

## D. Bila website belum normal

- Cari pesan terbaru dari `writable/logs/log-YYYY-MM-DD.log`.
- Jika log tidak dapat ditulis, buka cPanel → Metrics → Errors.
- Jika muncul `Session` write error, perbaiki `writable/session` (jangan mengganti session ke dummy).
- Jika muncul `route-id.key` error, cek `writable/secure`, pulihkan kunci asli dari backup atau atur `academy.urlIdKey` dengan kunci acak UNIK, rahasia dan stabil sepanjang umur aplikasi (jangan membuat acak baru setiap request).
- Jika muncul database table missing, pastikan migrasi V19/V20 telah dijalankan sebelumnya; **JANGAN jalankan `IMPORT_SEKALI.sql` di database lama**.
- Jika perubahan tidak terlihat, cek PHP OPcache server dan restart PHP-FPM melalui hosting jika memungkinkan; refresh browser Ctrl+F5.

## E. Keamanan

- Setelah password database dan OAuth secret pernah dipublikasikan, ROTASI keduanya di cPanel dan Google Cloud. Jangan simpan nilai asli di chat, kode, atau ZIP.
- Enkripsi ID pada URL tidak menggantikan pemeriksaan izin user dan admin.
- Folder `writable/` harus di luar document root `public/`. Jangan bagikan `.env` atau `route-id.key`.
- Source telah diperiksa secara statis, namun belum bisa menjamin integrasi produksi tanpa akses ke MySQL, OAuth dan PHP-FPM hosting.
