# Laporan parity CI3 ↔ CI4 (API `Json.php`) ## Status akhir (staging) | Indikator | Nilai | |-----------|--------| | **Readiness** | **SAFE FOR CUTOVER (API mobile, lingkungan staging yang diuji)** | | **Kondisi** | DB `dodolnan_bij` lokal; `php spark api:staging-validate` **35/35 PASS** (termasuk `--with-uploads` untuk `save_pp`). | | **Risiko sisa** | Lihat bagian *Risiko setelah staging* — bukan blocker untuk cutover API jika item ditindaklanjuti. | --- ## Validasi staging (otomatis) — 2026-04-18 ### Persiapan yang dilakukan - **`.env`** dibuat/diisi: koneksi DB selaras `application/config/database.php` CI3, `API_PARITY_LOG=true`, `app.appTimezone=UTC`, `app.baseURL` ke `public/`. - **Perintah:** `php spark api:staging-validate` dan `php spark api:staging-validate --with-uploads` - **Artefak:** `writable/staging/last-validation.json` (hasil mesin terbaru). ### Ringkasan hasil | Metrik | Nilai | |--------|--------| | Kasus uji dieksekusi | **35** | | Lulus | **35** | | Gagal | **0** | | Perbaikan kode pada sesi staging ini | **0** (tidak ada mismatch baru) | ### Cakupan per endpoint | Area | Apa yang diuji | |------|----------------| | **DB** | `SELECT 1` | | **Edge invalid** | `login`, `login_w_token`, `profil`, `presensi_today`, `presensi`, `save_*`, `batalkan_cuti`, `berita`, `cuti`, `lembur`, `libur`, `aktifitas`, `daftar_today`, `save_pp`, `save_password` dengan token kosong/salah | | **Token valid** (ambil token pertama di tabel `pegawai`) | `login_w_token`, `profil`, `presensi_today`, `presensi`, `berita`, `cuti`, `lembur`, `libur`, `aktifitas`, `daftar_today`, `save_istirahat` (mulai & selesai kosong — perilaku CI4 terdokumentasi) | | **Upload** | `--with-uploads`: `save_pp` dengan GIF 1×1 base64, verifikasi file di `public/assets/uploads/pengguna/`, hapus file, revert kolom `photo` | | **Folder upload** | Writable: `dokcuti`, `aktifitas`, `absen/masuk`, `absen/pulang`, `pengguna` | ### Yang belum diuji otomatis pada run ini - **`login` sukses** (username/password nyata) — hindari kredensial di repo; uji manual / env terpisah. - **`save_masuk` / `save_pulang` / `save_cuti` / `save_aktifitas` sukses** dengan foto base64 besar — hanya jalur invalid yang diuji otomatis. - **`batalkan_cuti` sukses**, **`save_password` sukses** — butuh id cuti valid / password env (`STAGING_VALIDATE_PASS` tersedia untuk cabang “password lama salah” saja). - **HTTP penuh** (CORS, `index.php`, reverse proxy) — pengujian CLI memanggil `MobileJsonService` langsung (setara logika controller). Untuk log `api_parity-*.log`, lakukan request HTTP ke `MobileJsonController` (logging tidak aktif di CLI). ### Log `api_parity-*.log` File ini diisi hanya saat request **HTTP** ke `MobileJsonController` dengan `API_PARITY_LOG=true`. Jalur Spark **tidak** menulis log tersebut. --- ## Perbaikan kompatibilitas (sesi sebelumnya — baseline) | Area | Masalah potensial vs CI3 | Perbaikan | |------|--------------------------|------------| | Serialisasi JSON | Formatter CI4 ≠ `json_encode` default CI3 | `MobileJsonController::respondLegacy()` memakai `json_encode(..., 0, 512)` + `setBody` | | `utf8ize` | Perbedaan dengan `utf8_encode` CI3 | `@utf8_encode()` untuk string | | `base64_decode` | Mode strict | Tanpa strict, seperti CI3 | | Upload | `file_put_contents` return `0` | Cek `=== false` + string kosong setelah decode | | `save_password` | `===` vs `==` | `==` seperti CI3 | --- ## Analisis statis (referensi) | Endpoint | Catatan | |----------|---------| | login | Struktur `status` / `pesan` / `token` | | login_w_token | Respons sukses tanpa `token` di JSON | | profil | Nested + `jadwal` | | presensi_today | `id_presensi` bentuk `{id}.` pada insert baru | | presensi | Tanpa `data` jika tidak ada baris | | save_masuk / save_pulang | Pesan & update | | save_istirahat | **Deviasi:** mulai & selesai keduanya kosong → CI4 tidak `UPDATE` (CI3 rawan undefined) | | save_aktifitas, save_cuti, batalkan_cuti | | | berita, cuti, lembur, libur, aktifitas, daftar_today | | | save_pp, save_password | | --- ## Risiko setelah staging 1. **Timezone produksi:** CI3 memakai `time_reference = local`; CI4 `.env` saat ini `UTC` — samakan dengan server CI3 produksi sebelum cutover (`app.appTimezone`). 2. **`app.baseURL`** harus benar untuk klien mobile / reverse proxy. 3. **Charset:** `.env` memakai `utf8` / `utf8_general_ci` selaras CI3; jika DB sudah `utf8mb4`, sesuaikan dan re-uji. 4. **Uji HTTP + log parity** ke endpoint `/json/*` atau `/api/mobile/*` sebelum matikan CI3. 5. **Upload berat & MIME** — uji manual dengan aplikasi nyata. --- ## Kesimpulan | Status | Kapan memakai | |--------|----------------| | **SAFE FOR CUTOVER (API mobile)** | Setelah staging ini: DB nyata, 35 kasus otomatis lulus, upload `save_pp` round-trip OK. Terapkan risiko #1–#4 di produksi. | | **NEEDS TESTING** | Jika DB / timezone / baseURL berubah atau belum ada uji HTTP dari klien mobile. | | **NOT READY** | Jika `api:staging-validate` gagal atau muncul mismatch baru — perbaiki, lalu perbarui laporan ini. | Perintah ulang validasi: ```bash cd bij.mwp.co.id-ci4 php spark api:staging-validate php spark api:staging-validate --with-uploads ```