# Laporan persiapan migrasi CI3 → CI4

**Sumber (tidak diubah):** `C:\laragon\www\bij-migration\bij.mwp.co.id`  
**Target:** `C:\laragon\www\bij-migration\bij.mwp.co.id-ci4` (CodeIgniter 4.7.x via `appstarter`)

**Indeks dokumen terbaru:** mulai dari [README.md](README.md) (controllers, models, routes, auth, risks, json_api_map, ROADMAP).

API mobile **sudah di-port** ke `App\Services\Mobile\MobileJsonService` + `MobileJsonController`; admin memakai layout dasar + aset TailAdmin di `public/assets/tailadmin/`.

Dokumen ini tetap memuat ringkasan awal + checklist; detail teknis dipindah ke file tema di folder yang sama.

---

## 1. Peta komponen CI3

### 1.1 Controller (`application/controllers/`)

| File | Peran singkat |
|------|----------------|
| `Json.php` | API JSON untuk aplikasi mobile (presensi, cuti, profil, dll.); query DB langsung di controller |
| `Site.php` | Frontend ringkas: redirect, halaman login, `login_auth` (Ion Auth) |
| `Cli.php` | Perintah CLI |
| `Errors.php` | Penanganan error |

Routing default: `application/config/routes.php` mengarah ke `site`; endpoint `Json` mengikuti konvensi CI3 `controller/method` (mis. `json/login`).

### 1.2 Model (`application/models/`)

| Model | Konteks tipikal |
|-------|-------------------|
| `User_model.php`, `Group_model.php`, `Admin_user_model.php`, `Api_key_model.php` | Pola CI Bootstrap / admin & API (bukan dipakai langsung oleh `Json.php` mobile) |

Catatan: logika mobile di `Json.php` **tidak** memakai model ini; data diambil lewat `$this->db` di controller.

### 1.3 Routes (`application/config/routes.php`)

- `default_controller` = `site`
- Pola **CI Bootstrap 3**: prefix bahasa `^(\w{2})/(.*)$`, routing REST `api/(:any)/(:num)` → modul `api`
- Tidak ada definisi eksplisit per method untuk `Json`; mengandalkan routing default CI3.

### 1.4 Modul HMVC (`application/modules/`)

| Modul | Isi penting |
|-------|-------------|
| **admin** | `Home`, `Pegawai`, `Presensi`, `Perusahaan`, `Laporan`, `Panel`, `Util`, `Errors`; views + Grocery CRUD / laporan |
| **api** | `Home`, `Swagger`, `Errors`; library `Jwt_client.php` (Firebase JWT)—**alur mobile `Json.php` memakai token string di tabel `pegawai`, bukan JWT ini** |
| **adminlte** | `Widget.php`—komponen UI |

HMVC memakai **MX_Controller** (lihat `application/core/MY_Controller.php`).

### 1.5 Auth

- **Web admin / site:** **Ion Auth** (`ion_auth` di autoload), login di `Site::login_auth`, pembatasan halaman lewat `mPageAuth` + `ion_auth->in_group()` di `MY_Controller`.
- **Mobile (`Json.php`):** autentikasi **stateless token** disimpan kolom `pegawai.token`, password **MD5** di tabel; tidak memakai Ion Auth di controller ini.

### 1.6 Helper & library custom (ringkas)

**Helpers** (`application/helpers/`): `MY_string_helper.php`, `MY_url_helper.php`, `MY_directory_helper.php`.

**Libraries** (akar `application/libraries/`, selain vendor besar):

- `Data_importer.php`, `Form_builder.php`, `System_message.php`
- `MY_Email.php`, `MY_Form_validation.php`, `MY_Pagination.php`
- `PHPExcel.php` + pohon **PHPExcel** (usang; di CI4 ganti **PhpSpreadsheet**)

**Autoload** (`application/config/autoload.php`): paket `ion_auth`, `grocery_crud`, `image_crud`, `rest_server`; library `database`, `ion_auth`, `form_validation`.

**Third party** (indikasi): Ion Auth, Grocery CRUD, Image CRUD, REST server (lihat folder `application/third_party/` bila perlu detail).

---

## 2. Audit `application/controllers/Json.php`

### 2.1 Daftar method publik

| Method | Kategori |
|--------|----------|
| `index` | Penolakan akses |
| `login_w_token` | Login / token |
| `login` | Login / token |
| `profil` | Pegawai / mobile |
| `save_cuti` | Cuti + upload / mobile |
| `batalkan_cuti` | Cuti / mobile |
| `save_aktifitas` | Aktivitas + upload / mobile |
| `save_masuk` | Presensi + geo + foto / mobile |
| `save_pulang` | Presensi + geo + foto / mobile |
| `save_istirahat` | Presensi / mobile |
| `presensi_today` | Presensi / mobile |
| `presensi` | Presensi / mobile |
| `daftar_today` | Presensi / daftar rekan / mobile |
| `berita` | Konten / mobile |
| `cuti` | Cuti / mobile |
| `lembur` | Lembur / mobile |
| `libur` | Master libur / mobile |
| `aktifitas` | Aktivitas / mobile |
| `save_pp` | Profil foto / mobile |
| `save_password` | Auth password / mobile |

Private: `generateRandomString`, `utf8ize`.

### 2.2 Login, token, pegawai, endpoint mobile

- **Login / token:** `login`, `login_w_token` (semua method lain memakai `token` POST untuk identitas pegawai).
- **Pegawai:** `profil`, `save_pp`, `save_password`; seluruh alur memuat baris `pegawai` lewat token.
- **Endpoint mobile (khas app):** semua di atas kecuali `index`; pola respons JSON + header `Access-Control-Allow-Origin: *` (CORS permisif).

### 2.3 Query langsung ke database

Seluruh file memakai **Active Record / query builder CI3** (`$this->db->...`) **di dalam controller**—tidak lewat model. Setiap method melakukan satu atau lebih: `from`, `where`, `get`, `insert`, `update`, `join`, dll. Tabel yang muncul: antara lain `pegawai`, `kantor`, `jabatan`, `unit_kerja`, `lembur`, `dilapangan`, `libur`, `cuti`, `jadwal`, `presensi`, `berita`, `cuti_dokumen`, `aktifitas_harian`.

### 2.4 Refactor besar yang disarankan

1. **Keamanan:** password **MD5**; token prediktabil (bagian `md5(id_pegawai)` + random); token disimpan plain di DB; **tanpa rate limiting** di controller.
2. **Arsitektur:** pindahkan query ke **Model** / **Repository** / **Service**; controller hanya HTTP + validasi.
3. **Upload:** base64 → file via helper `file`; path relatif `./assets/uploads/...`—di CI4 gunakan `Writable`/filesystem config, validasi MIME/size, nama file aman.
4. **`utf8ize` memakai `utf8_encode()`** — perilaku usang/deprecated di PHP modern; sebaiknya konsisten **UTF-8** dari DB dan `json_encode` dengan flag yang tepat.
5. **`daftar_today`:** tanggal di-inline ke string join (`date("Y-m-d")`)—risiko konsistensi; sebaiknya **binding parameter** / query builder terpisah.
6. **`save_pulang`:** variabel toleransi memakai field `toleransi_terlambat` untuk batas pulang—perlu verifikasi apakah itu maksud bisnis atau bug (copy-paste dari masuk).
7. **CORS `*`** + POST form-style: tinjau ulang untuk produksi (origin spesifik, HTTPS, CSRF untuk web—mobile biasanya token header).

Detail baris-per-baris ada di file pendamping `audit-json-controller.md` (folder yang sama).

---

## 3. Komponen: pindah langsung vs tulis ulang vs ditinggalkan

### 3.1 Bisa dipindahkan / diadaptasi dengan effort kecil–sedang

- Pola respons JSON `{ status, pesan, ... }` — pertahankan sementara untuk kompatibilitas klien mobile.
- Struktur query bisnis (jadwal harian, insert `presensi` harian) — logika bisa dipindah ke service dengan sedikit penyesuaian API CI4 DB.
- Helper custom yang murni string/url — port bertahap ke helper CI4 atau class util.

### 3.2 Harus ditulis ulang (disarankan)

- **Autentikasi mobile:** ganti MD5 → `password_hash` / verifikasi modern; token → **JWT** atau session server + refresh; invalidasi token.
- **Seluruh lapisan akses data** untuk API mobile — model CI4, validasi input, transaction di operasi multi-tabel.
- **Ion Auth + HMVC admin** — di CI4 umumnya modul terpisah atau admin berdiri sendiri; tidak ada port 1:1 HMVC MX.
- **PHPExcel** — ganti **PhpSpreadsheet**.
- **Grocery CRud / Image Crud** — evaluasi CI4 admin scaffold atau CRUD custom / paket modern.

### 3.3 Sebaiknya ditinggalkan atau diganti

- **PHPExcel** sebagai dependensi jangka panjang.
- **CORS `*`** di API sensitif data kepegawaian.
- Duplikasi besar potongan “decode base64 + write_file + insert DB” di banyak method — ganti satu **UploadService** + policy keamanan.

---

## 4. Struktur di target CI4 (aman, tanpa ubah vendor framework)

- `app/Controllers/Api/MobileJsonController.php` — endpoint API mobile.
- `app/Services/Mobile/MobileJsonService.php` — port logika dari `Json.php`.
- `app/Libraries/LegacyUtf8Encoder.php` — setara `utf8ize` untuk string ISO-8859-1.
- `app/Config/Routes.php` — grup `api/mobile/*` dan alias **`json/*`**.
- `app/Controllers/Admin/Dashboard.php` + `app/Views/layouts/*`, `app/Views/pages/dashboard.php` — foundation admin + TailAdmin assets di `public/assets/tailadmin/`.
- `public/assets/uploads/*` — folder upload (dengan `.gitkeep`).

---

## 5. Checklist migrasi bertahap

Gunakan urutan ini; centang setelah tiap fase stabil di staging.

### Fase A — Lingkungan & data

1. [ ] Samakan versi PHP target dengan CI4; backup DB produksi.
2. [ ] Dokumentasikan skema tabel yang dipakai `Json.php` (ER ringkas atau export struktur saja).
3. [ ] `.env` CI4: koneksi DB terpisah / read-only untuk eksperimen awal (opsional).

### Fase B — API mobile (prioritas kompatibilitas klien)

4. [x] Implementasi `login` + `login_w_token` (+ endpoint lain) di CI4 — **kode siap**; verifikasi di staging wajib.
5. [ ] Pindahkan validasi pegawai-by-token ke **filter** / **service** tunggal (`MobileAuthService`).
6. [ ] `profil` — ekstrak query ke model; tes parity JSON dengan CI3.

### Fase C — Presensi & file

7. [ ] `presensi_today` + insert baris harian — transaction + tes race condition.
8. [ ] `save_masuk` / `save_pulang` / `save_istirahat` — satu domain **PresensiService**; perbaiki logika toleransi jika sudah diverifikasi user bisnis.
9. [ ] Unified handler upload (cuti / aktivitas / absen / profil) + storage path CI4 (folder `public/assets/uploads` sudah disiapkan).

### Fase D — Fitur sekunder mobile

10. [ ] Cuti: `cuti`, `save_cuti`, `batalkan_cuti` + relasi dokumen.
11. [ ] `berita`, `lembur`, `libur`, `aktifitas`, `daftar_today`.
12. [ ] `save_password` — bcrypt + policy password.

### Fase E — Admin & HMVC

13. [ ] Inventarisasi modul `admin` per controller; rencanakan modul CI4 (Shield, custom admin, atau SPA terpisah).
14. [ ] Ganti PHPExcel di laporan; uji cetak/ekspor.
15. [ ] Matikan rute CI3 untuk endpoint yang sudah dialihkan; proxy bertahap atau cutover DNS.

### Fase F — hardening

16. [ ] CORS ketat, HTTPS, rate limit login, audit log presensi.
17. [ ] Hapus dependensi yang tidak terpakai; tes beban ringan pada endpoint paling sering dipanggil.

---

*Dibuat sebagai artefak persiapan migrasi; sumber CI3 tidak dimodifikasi.*
