# Menjalankan SIPENILIK dengan database

Data bersama kini disimpan pada MySQL/MariaDB melalui PHP PDO. Browser menyimpan cache sementara dan mengirim perubahan setiap 60 detik selama akun masuk. Pendaftaran dan keputusan persetujuan dikirim langsung ke server agar kata sandi tidak disimpan di antrean browser.

## Persyaratan

- PHP 8.1 atau lebih baru dengan ekstensi `pdo_mysql`
- MySQL 8+ atau MariaDB yang mendukung `InnoDB`, `utf8mb4`, dan kolom timestamp presisi
- HTTPS untuk penggunaan selain pengembangan lokal

## Instalasi awal

1. Buat database kosong, misalnya `sipenilik`.
2. Jalankan [database/schema.sql](./database/schema.sql) pada database tersebut.
   Untuk database yang sudah dibuat sebelum perubahan kolom NIK/NUPTK, jalankan satu kali [database/migration_001_nik_nuptk.sql](./database/migration_001_nik_nuptk.sql). Migrasi ini memperlebar kolom identitas tanpa menghapus data.
3. Atur variabel lingkungan PHP. Contoh PowerShell:

   ```powershell
   $env:SIPENILIK_DB_DSN = "mysql:host=127.0.0.1;dbname=sipenilik;charset=utf8mb4"
   $env:SIPENILIK_DB_USER = "sipenilik_app"
   $env:SIPENILIK_DB_PASSWORD = "ganti-dengan-rahasia-database"
   $env:SIPENILIK_ADMIN_PASSWORD = "kata-sandi-admin-minimal-12-karakter"
   $env:SIPENILIK_PENILIK_PASSWORD = "kata-sandi-penilik-minimal-12-karakter"
   ```

   Gunakan rahasia yang berbeda dan simpan di konfigurasi server, bukan di source code.

   Untuk hosting yang tidak menyediakan pengaturan environment variable, salin
   `api/config.local.example.php` menjadi `api/config.local.php`, lalu isi host,
   nama database, username, dan password pada file lokal tersebut. File lokal
   ini diabaikan Git dan akses web-nya diblokir oleh `api/.htaccess`; jangan
   unggah ke repositori publik.

4. Jalankan satu kali dari root aplikasi:

   ```powershell
   php .\api\initialize.php
   ```

   Inisialisasi ini **menghapus akun lain dan pendaftaran pending**, lalu hanya menyiapkan Admin Utama (`admin.dinas`) dan Penilik Asep (`198507042009021002`). Jalankan hanya pada database yang memang ditujukan untuk aplikasi SIPENILIK.
   Kredensial awal yang dibuat untuk pemilik aplikasi dicatat terpisah di `KREDENSIAL_LOGIN_SIPENILIK.txt`; atur kedua variabel kata sandi sesuai catatan sebelum menjalankan inisialisasi. Simpan catatan itu secara privat dan jangan unggah ke server publik.

5. Untuk uji lokal, dari root aplikasi jalankan:

   ```powershell
   php -S 127.0.0.1:8000
   ```

   Buka `http://127.0.0.1:8000/sipenilik.html`. Jangan membuka `sipenilik.html` langsung sebagai `file://`: endpoint PHP dan sinkronisasi database tidak akan berjalan.

## Reset kata sandi Admin

Jika kata sandi `admin.dinas` tidak dapat digunakan, reset hanya kata sandi akun tersebut tanpa menjalankan initializer. Pastikan `api/config.local.php` sudah tersedia di hosting, lalu jalankan dari Terminal/SSH pada folder aplikasi:

```sh
read -s -p "Kata sandi Admin baru: " SIPENILIK_ADMIN_PASSWORD
export SIPENILIK_ADMIN_PASSWORD
echo
php api/reset_admin_password.php
unset SIPENILIK_ADMIN_PASSWORD
```

Gunakan kata sandi baru minimal 12 karakter. Skrip hanya memperbarui hash kata sandi `admin.dinas`; skrip tidak mengaktifkan akun dan tidak menghapus atau mengubah akun maupun pendaftaran lain. Hapus `api/reset_admin_password.php` dari hosting setelah berhasil dijalankan. Skrip hanya dapat dijalankan lewat PHP CLI, bukan browser.

## Data dan sinkronisasi

- Tabel `app_accounts` berisi akun dan hash kata sandi PHP; `app_registrations` menyimpan antrean pendaftaran beserta hash kata sandi; `app_state` menyimpan data aplikasi yang disinkronkan.
- Pengaturan akun Penilik memverifikasi kata sandi saat ini dan menyimpan username serta hash kata sandi baru di server; kredensial tidak disimpan pada `localStorage`.
- Pendaftaran Kepala PKBM memakai label NIK/NUPTK dan tidak mensyaratkan jumlah digit tertentu; kolom database menerima identitas sampai 100 karakter. Akun Penilik dan Staf Dinas tetap menggunakan label NIP.
- Saat halaman dibuka, sesi server dan branding login dimuat. Setelah login, state aplikasi ditarik/dikirim lagi setiap 60 detik. Perubahan lokal yang bersamaan dengan perubahan server diselesaikan dengan mempertahankan revisi server yang lebih baru.
- Antrean pendaftaran, persetujuan, penolakan, status akun, dan perubahan wilayah disimpan langsung ke database.
- Data cache di browser dibersihkan/dibatasi melalui migrasi akun satu kali: akun terkelola selain Admin Utama dan Asep serta data akun Kepala PKBM/Tutor yang lama dihapus. Data laporan dan profil Penilik tidak ikut dihapus.
- Berkas konfigurasi koneksi memakai environment variables; akses HTTP langsung ke `api/config.php` ditolak oleh `.htaccess` pada Apache. Pastikan aturan perlindungan serupa diterapkan jika memakai web server lain.
