# Porting katalog publik dan keranjang

Tanggal: 17 Oktober 2026.

## Cakupan selesai

| Sumber di `pos/` | Controller CI4 | Route publik |
| --- | --- | --- |
| `stores.php` | `PublicStore` | `stores`, `stores.php` |
| `store_product.php` | `PublicProduct` | `store_product`, `store_product.php` |
| `cart.php` | `PublicCart` | `cart`, `cart.php` |

Katalog mempertahankan pencarian, kategori, pengurutan, statistik penjualan, informasi toko, daftar produk/rental aktif, galeri, produk terkait, varian, tambahan, berbagi tautan, serta pemesanan melalui tautan WhatsApp. Pencatatan pengunjung dan tabel tambahan bersifat best effort. Halaman hanya menampilkan toko/produk aktif. Query memakai binding parameter dan pengurutan terbatas pada pilihan yang dikenal.

Keranjang memakai sesi pengunjung tanpa memerlukan login kasir. `App\Libraries\PublicCart` mengambil harga, nama, gambar, stok dan toko dari database; pembacaan/perubahan memperbarui snapshot dan menghapus produk tidak tersedia. Jumlah dibatasi stok terkini. Menambah produk toko lain mengganti isi keranjang seperti aplikasi sumber. Keranjang belum mengurangi/memesan stok; checkout harus memvalidasi kembali di dalam transaksi sebelum mencatat pesanan.

`GET cart.php?action=get` mengembalikan isi/jumlah/total. `add`, `update`, `remove`, `clear` memerlukan POST dan CSRF. JSON menyertakan `csrf_token` terbaru, dan kedua halaman memperbarui token setelah respons. GET yang meminta perubahan ditolak (405), input angka/array tidak valid ditolak, kegagalan database tidak membocorkan detail internal. Respons memakai `Cache-Control: no-store`.

Pilihan varian/tambahan menggunakan tombol pesan WhatsApp. Keranjang sumber hanya menyimpan produk utama; detail produk CI memberi arahan untuk menggunakan WhatsApp bila pilihan tersebut aktif agar pilihan tidak hilang diam-diam. Tidak ada pesan WhatsApp yang dikirim saat validasi otomatis.

## Validasi

- Seluruh suite: **317 tes, 2.310 assertion**, lulus.
- Tambahan 19 tes/58 assertion mencakup route publik, batas stok, harga dari database, pergantian toko, produk hilang/berpindah toko, update/remove/clear, CSRF, larangan mutasi melalui GET, input rusak, binding pencarian, kegagalan tracking, dan render kedua view (termasuk escaping nama produk dalam JavaScript).
- PHP lint seluruh controller/view/helper/library/command/unit test dan Routes.php; JavaScript kedua view diperiksa dengan Node.
- Belum diuji melalui browser dan database aplikasi nyata. Salin aset/upload yang diperlukan sebelum uji tampilan di deployment.

## Belum selesai

Tahap ini menyelesaikan **3 dari 20 file utama/publik** yang tersisa setelah admin. Masih **17 file**:

1. `booking_api.php`
2. `checkout.php`
3. `checkout_otp.php`
4. `checkout_rental.php`
5. `checkout_rental_otp.php`
6. `checkout_rental_special.php`
7. `checkout_rental_success.php`
8. `checkout_success.php`
9. `forgot_password.php`
10. `order_meja.php`
11. `pricing.php`
12. `register.php`
13. `store_rental.php`
14. `store_rental_schedule.php`
15. `tracking.php`
16. `upgrade.php`
17. `web1.php`

Tautan checkout, detail rental dan beranda pencarian dari katalog masih mengarah ke tahap yang belum selesai; belum dapat dipakai sebagai alur checkout produksi. Berikutnya porting `checkout.php`, `checkout_otp.php`, `checkout_success.php` sebagai satu alur pesanan, kemudian booking/rental dan halaman publik lainnya.

## Pembaruan checkout — 17 Oktober 2026

`checkout.php`, `checkout_otp.php`, dan `checkout_success.php` sudah diporting; daftar 17 file di atas adalah catatan akhir tahap katalog. Sisa terbaru **14 file**. Lihat [PORTING_CHECKOUT.md](PORTING_CHECKOUT.md) untuk perilaku, persyaratan database, hasil validasi, dan daftar terbaru.

## Status akhir — 17 Oktober 2026

Seluruh file PHP yang tersisa sudah diporting. Sisa terbaru **0**; lihat [PORTING_SELESAI.md](PORTING_SELESAI.md) dan [PORTING_INVENTARIS.md](PORTING_INVENTARIS.md). Angka sisa di atas adalah catatan historis tahap ini.
