# SUPERAPP ACADEMY V14 — FULL SOURCE

Versi: V14.0.0, berbasis V13 + CI4.7.6, PHP 8.2+, MySQL/MariaDB, antarmuka WITA (Asia/Makassar).

## Perubahan V14

1. Semua konten gratis dan berbayar yang ditawarkan sebagai produk harus **masuk keranjang dan checkout**. Checkout Rp0 membuat order `paid` internal secara langsung, **tanpa payment gateway**, lalu memberikan hak akses.
2. Tryout Akbar (meski gratis) dan tryout lain yang diaktifkan pendaftaran/kuotanya wajib checkout. `registration_open_at` / `registration_close_at` diatur admin, kuota dapat berupa 50 atau angka lain.
3. Kapasitas dihitung saat checkout, bukan dari jumlah peserta yang memulai CAT. Kursi gratis langsung `confirmed`. Kursi berbayar menjadi `reserved` sampai pembayaran terverifikasi dan batas waktu habis. Perhitungan mengunci baris `exams` memakai MySQL InnoDB `FOR UPDATE`.
4. Jumlah pendaftar terkonfirmasi, kursi tertahan, sisa kursi, dan nomor antrean terlihat di halaman yang relevan. Tampilan hitung mundur WITA dan pembaruan statistik publik berkala; **server menjadi sumber kebenaran**.
5. Paket member Silver, Gold, Platinum (awalnya `draft`) dan tier tambahan yang dibuat admin. Ubah harga, deskripsi, lama akses, dan status melalui `Panel Admin → Paket Member`. Hubungkan tier ke bundle pada `Penjualan & Bundle`.
6. TinyMCE Open Source GPL pada ringkasan/deskripsi/artikel di panel admin. Editor dimuat dari CDN jsDelivr, membutuhkan internet; jika tidak tersedia, textarea HTML tetap bisa dipakai. HTML disanitasi pada server untuk mengurangi risiko XSS. Editor tidak mengaktifkan unggah gambar atau plugin premium.
7. Semua kemampuan V13 tetap ada: bank soal banyak ujian, nilai gabungan dan ranking per bank, latihan dengan pembahasan, serta ekspor-impor ZIP bank soal.

## Pemasangan V13 → V14 (database berisi data)

**WAJIB** backup database SQL, seluruh folder lama, `.env`, dan `writable/` termasuk uploads sebelum memulai. Gunakan pemasangan staging lebih dahulu, terutama bila pengguna sudah melakukan pembayaran.

1. Di phpMyAdmin pilih database V13 yang benar; impor **hanya** `database/UPGRADE_V13_KE_V14.sql` satu kali. Tidak perlu menghapus tabel lama. Jangan impor `IMPORT_SEKALI.sql` ke database berisi data.
2. Ekstrak source V14 (folder `app/`, `public/`, `system/`, `database/`, dll.) ke folder aplikasi. File ini lengkap sehingga dapat replace source V13.
3. **Jangan menimpa kredensial asli di `.env` dengan placeholder ZIP.** Jika ingin benar-benar replace seluruh file termasuk `.env`, salin terlebih dahulu nilai database, domain, Google OAuth, token pembayaran dan WA lama ke `.env` baru.
4. Pertahankan data `writable/uploads`, session dan informasi yang relevan dari instalasi sebelumnya. Pastikan `writable/` dapat ditulis PHP.
5. Domain document root mengarah ke `public/`, PHP 8.2+ ekstensi intl, mbstring, mysqli, openssl, json; untuk export bank V13 perlu ekstensi `zip`.
6. Cek `app/Config/App.php` timezone `Asia/Makassar` atau WITA. Pastikan jam server sinkron, karena pembukaan WAR menggunakan jam **server**, bukan jam JavaScript peserta.
7. Admin → Tryout Akbar: buat/jadwalkan `Pendaftaran Dibuka`, `Pendaftaran Ditutup`, `Kuota Pendaftaran=50`, Akses Gratis/Berbayar, lalu pilih bank soal dan terbitkan. Situs otomatis membuat produk satuan untuk ujian gratis **dan** berbayar.
8. Admin → Paket Member: aktifkan Silver/Gold/Platinum atau buat tier lain; atur harga dan masa akses. Admin → Penjualan & Bundle: buat bundle berisi minimal dua konten, pilih `Member Tier` dan status `Terbit`.
9. Admin → Pengaturan: atur masa tahan kursi berbayar 5–180 menit (default 30). Pengguna berbayar perlu menyelesaikan gateway/manual sebelum reservasi berakhir.
10. Pengujian dengan dua peserta dan 1 kuota dahulu (staging): checkout gratis pertama berhasil, peserta kedua gagal dengan pesan kuota penuh; simulasi dua browser pada waktu yang sama untuk memeriksa transaksi InnoDB.

### Pemasangan baru

Gunakan database **kosong** dan impor `database/IMPORT_SEKALI.sql` satu kali. SQL ini sudah mencakup V14, **jangan** dilanjutkan dengan upgrade V13→V14. Isikan `.env` dan terapkan Google OAuth sebelum login.

## Ketentuan penting

- **Keranjang tidak mengunci kursi.** Ketika tombol checkout ditekan dan transaksi DB berhasil, peserta menerima kursi; pengguna yang checkout belakangan tidak otomatis masuk jika kuota habis.
- **Checkout gratis (Rp0)** langsung membuat order dan konfirmasi antrean tanpa gateway. Tidak ada pembelian gratis yang otomatis terbuka tanpa checkout.
- **Pembatalan admin:** pesanan transfer manual yang dibatalkan akan segera melepaskan kursi reservasi yang belum dikonfirmasi.
- **Checkout berbayar:** kursi disimpan sementara (misalnya 30 menit), hingga penyedia gateway memberi callback sah atau admin mengonfirmasi transfer. Jika transaksi masuk setelah reservasi hangus, aplikasi menolak aktivasi otomatis. Admin perlu rekonsiliasi/refund secara manual menurut kebijakan merchant.
- Member tier merepresentasikan produk **bundle**. Produk tetap mempunyai `product_items` berisi materi, bank soal, ujian, dan kelas yang akan diberikan. Lama aktif dihitung dari checkout/aktivasi; pembelian ulang member memperpanjang tier tersebut.
- Jika sebuah tryout berkuota disertakan di kelas/bundle/member yang sudah dimiliki, harga **produk ujian satuan** menjadi Rp0 selama akses terkait aktif, tetapi peserta **tetap wajib mendaftar** dan checkout agar mendapat kursi. Pembelian kelas/bundle/member **tidak mengunci atau memesan kuota**, sehingga dapat dilakukan sebelum jadwal WAR tanpa merebut kursi.
- Fitur editor TinyMCE menggunakan lisensi GPL bila memilih mode `license_key:'gpl'`. Untuk instalasi komersial tertutup, evaluasi kepatuhan GPL atau beli lisensi komersial sesuai aturan TinyMCE.
- Data sensitif (kunci jawaban, password, token gateway) tidak ditampilkan pada API statistik kuota publik.

## Diagnosa jika muncul `Whoops!`

Baca file terbaru di `writable/logs/`, cari `CRITICAL`/`ERROR`. Penyebab umum: upgrade SQL belum dijalankan, `.env` salah, ekstensi `mysqli`/`intl` tidak aktif, folder `writable` tidak dapat ditulis. Untuk server produksi **jangan mengaktifkan debug publik**.

## Uji lokal yang sudah tersedia

```
php tests/smoke_v14.php
php tests/smoke_v12.php
php tests/smoke_bank_archive_v13.php
```

**Batas verifikasi:** php lint/tes logika dapat dijalankan tanpa MySQL, tetapi tes concurrency kuota, callback gateway asli, dan TinyMCE melalui browser perlu dilakukan di server/staging Anda.
