# Aplikasi Usulan Perbaikan Inventaris

**Aplikasi Usulan Perbaikan Inventaris Perwakilan BKKBN Provinsi Sumatera Utara**

Skripsi oleh **Renanda Nauval (NIM 2112000080)** — Program Studi Informatika.

## Persyaratan Sistem

- PHP 8.2 atau lebih baru
- MySQL atau MariaDB
- Composer
- Apache melalui XAMPP atau Laragon

## Teknologi

- PHP Native 8.2+
- MySQL/MariaDB
- PDO
- HTML, CSS, JavaScript
- Bootstrap 5 (CDN)
- Composer
- Arsitektur MVC sederhana

## Instalasi

### 1. Pasang Dependensi

```cmd
composer install
```

### 2. Buat File .env

```cmd
copy .env.example .env
```

Sesuaikan konfigurasi database pada file `.env`:

```env
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_usulan_perbaikan
DB_USERNAME=root
DB_PASSWORD=
UPLOAD_MAX_SIZE_MB=5
UPLOAD_MAX_FILES=5
LOGIN_MAX_ATTEMPTS=5
LOGIN_DECAY_MINUTES=15
```

### 3. Buat Database

Buka phpMyAdmin atau terminal MySQL, lalu jalankan:

```sql
CREATE DATABASE db_usulan_perbaikan
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
```

### 4. Impor File SQL

Impor file berikut melalui phpMyAdmin atau terminal:

```text
database/database.sql
```

File baseline tersebut memuat seluruh tabel inti sampai `work_logs`, termasuk indeks dan foreign key yang dibutuhkan instalasi baru. Folder `database/migrations/` dipertahankan sebagai riwayat perubahan bertahap untuk database yang sudah berjalan; jangan menjalankan ulang migration yang telah tercatat.

### 5. Siapkan Akun Pengembangan

Empat akun demo dibuat melalui seeder PHP agar kata sandi selalu diproses dengan `password_hash()`.
Pada PowerShell, jalankan:

```powershell
$env:DEV_SEED_PASSWORD='BkkbnDemo!2026'
php database/seeders/seed_development_users.php
Remove-Item Env:DEV_SEED_PASSWORD
```

Seeder hanya dapat berjalan saat `APP_ENV` bernilai `local` atau `development`. Password awal lokal adalah `BkkbnDemo!2026`. Ganti kata sandi melalui menu profil setelah masuk dan jangan gunakan akun demo pada production.

Siapkan enam data aset representatif untuk pengembangan:

```powershell
php database/seeders/seed_development_assets.php
```

### 6. Regenerasi Autoload

```cmd
composer dump-autoload
```

## Keamanan File Konfigurasi

- Jangan membagikan file `.env`.
- Paket proyek hanya menyertakan `.env.example`.
- Jalankan `composer install` setelah ekstraksi karena folder `vendor/` tidak disertakan.
- Direktori internal dilindungi oleh `.htaccess`, tetapi deployment produksi tetap sebaiknya menggunakan folder `public/` sebagai document root.
- Sesi pengguna divalidasi ulang terhadap status akun dan role pada database; akun yang dinonaktifkan atau berubah identitas keamanannya wajib login kembali.
- Respons aplikasi mengirim CSP, larangan framing lintas origin, kebijakan permission browser, dan cache `no-store`; HSTS aktif otomatis saat request benar-benar menggunakan HTTPS.
- Foto tiket tetap disimpan di `storage/uploads/`, divalidasi berdasarkan MIME serta isi gambar, dan hanya disajikan melalui controller berizin.
- Logger meredaksi field password, token, secret, authorization, cookie, dan API key sebelum ditulis.

## Menjalankan Aplikasi

Letakkan folder proyek di dalam direktori web server:

- XAMPP: `C:\xampp\htdocs\`
- Laragon: `C:\laragon\www\`

Lalu akses melalui browser:

```text
http://localhost/bkkbn_eticketing/public
```

## Ringkasan Deployment Produksi

Untuk produksi, gunakan Apache dengan document root langsung ke folder `public/`, HTTPS valid, `APP_ENV=production`, `APP_DEBUG=false`, user database berhak minimal, serta permission tulis hanya pada subfolder `storage` yang diperlukan. Instal dependensi dengan:

```bash
composer install --no-dev --optimize-autoloader
```

Instalasi database baru memakai `database/database.sql`. Database lama memakai migration 001–010 secara berurutan dan hanya untuk migration yang belum diterapkan. Jangan menjalankan seeder development pada produksi. Panduan lengkap deployment, Apache, PHP upload, cron, backup, dan recovery tersedia di `docs/24-DEPLOYMENT-BACKUP-DAN-RECOVERY.md`.

Gunakan `.env.production.example`, `deploy/apache/bkkbn-eticketing.conf.example`, dan `deploy/php/production.ini.example` sebagai template. Setelah konfigurasi server serta data production tersedia, jalankan gerbang kesiapan:

```bash
composer validate --strict
composer audit --locked
composer production-check
```

Production bootstrap bersifat fail-closed: konfigurasi berbahaya seperti debug aktif, URL non-HTTPS, user database root, password kosong/placeholder, atau seed password terisi menghasilkan HTTP 503. Detail lengkap tersedia di `docs/28-PRODUCTION-READINESS.md`.

## Pengingat SLA Otomatis

Command pengingat hanya dapat dijalankan melalui PHP CLI:

```powershell
php bin/sla-reminders.php
```

Jadwalkan setiap 15 menit. Untuk Windows Task Scheduler pada instalasi XAMPP, gunakan:

```text
Program/script : C:\xampp\php\php.exe
Arguments      : "D:\XAMPP\htdocs\bkkbn_eticketing\bin\sla-reminders.php"
Start in       : D:\XAMPP\htdocs\bkkbn_eticketing
```

Contoh cron Linux:

```cron
*/15 * * * * cd /var/www/bkkbn_eticketing && /usr/bin/php bin/sla-reminders.php >> storage/logs/sla-reminders-cron.log 2>&1
```

Command memakai zona waktu `Asia/Jakarta`. Notifikasi mendekati tenggat dibuat satu kali untuk nilai SLA yang sama, sedangkan notifikasi keterlambatan maksimal satu kali per hari untuk setiap penerima. Ringkasan eksekusi dicatat ke `storage/logs/app.log`; tiket selesai diabaikan dan status proses tidak diubah.

## URL Penting

| Halaman | URL |
|---------|-----|
| Login | `http://localhost/bkkbn_eticketing/public/login` |
| Redirect dashboard | `http://localhost/bkkbn_eticketing/public/dashboard` |
| Daftar tiket Pegawai | `http://localhost/bkkbn_eticketing/public/pegawai/tiket` |
| Buat tiket Pegawai | `http://localhost/bkkbn_eticketing/public/pegawai/tiket/buat` |
| Detail tiket Pegawai | `http://localhost/bkkbn_eticketing/public/pegawai/tiket/{ticket_id}` |
| Revisi tiket Pegawai | `http://localhost/bkkbn_eticketing/public/pegawai/tiket/{ticket_id}/revisi` |
| Dashboard TU | `http://localhost/bkkbn_eticketing/public/tu/dashboard` |
| Antrean pemeriksaan TU | `http://localhost/bkkbn_eticketing/public/tu/tiket/pemeriksaan` |
| Tiket disetujui / menunggu SLA | `http://localhost/bkkbn_eticketing/public/tu/tiket/disetujui` |
| Penetapan SLA TU | `http://localhost/bkkbn_eticketing/public/tu/tiket/{ticket_id}/sla` |
| Penugasan Teknisi oleh TU | `http://localhost/bkkbn_eticketing/public/tu/tiket/{ticket_id}/penugasan` |
| Pemantauan SLA TU | `http://localhost/bkkbn_eticketing/public/tu/pemantauan` |
| Laporan operasional TU | `http://localhost/bkkbn_eticketing/public/tu/laporan` |
| Daftar riwayat aset TU | `http://localhost/bkkbn_eticketing/public/tu/aset` |
| Riwayat aset TU | `http://localhost/bkkbn_eticketing/public/tu/aset/{asset_id}/riwayat` |
| Audit tiket TU | `http://localhost/bkkbn_eticketing/public/tu/tiket/{ticket_id}/audit` |
| Detail pemeriksaan TU | `http://localhost/bkkbn_eticketing/public/tu/tiket/{ticket_id}/periksa` |
| Pengajuan tiket ke Pimpinan | `http://localhost/bkkbn_eticketing/public/tu/tiket/{ticket_id}/ajukan-pimpinan` |
| Dashboard Pimpinan | `http://localhost/bkkbn_eticketing/public/pimpinan/dashboard` |
| Laporan operasional Pimpinan | `http://localhost/bkkbn_eticketing/public/pimpinan/laporan` |
| Riwayat aset Pimpinan | `http://localhost/bkkbn_eticketing/public/pimpinan/aset/{asset_id}/riwayat` |
| Audit tiket Pimpinan | `http://localhost/bkkbn_eticketing/public/pimpinan/tiket/{ticket_id}/audit` |
| Antrean persetujuan Pimpinan | `http://localhost/bkkbn_eticketing/public/pimpinan/persetujuan` |
| Detail persetujuan Pimpinan | `http://localhost/bkkbn_eticketing/public/pimpinan/tiket/{ticket_id}/persetujuan` |
| Setujui tiket Pimpinan (POST) | `http://localhost/bkkbn_eticketing/public/pimpinan/tiket/{ticket_id}/setujui` |
| Tolak tiket Pimpinan (POST) | `http://localhost/bkkbn_eticketing/public/pimpinan/tiket/{ticket_id}/tolak` |
| Profil | `http://localhost/bkkbn_eticketing/public/profile` |
| Ubah kata sandi | `http://localhost/bkkbn_eticketing/public/change-password` |

## Akun Lokal

Seluruh akun berikut menggunakan password awal `BkkbnDemo!2026` setelah seeder dijalankan:

| Username | Role | Dashboard |
|----------|------|-----------|
| `pegawai` | PEGAWAI | `/pegawai/dashboard` |
| `tu` | TU | `/tu/dashboard` |
| `pimpinan` | PIMPINAN | `/pimpinan/dashboard` |
| `teknisi` | TEKNISI | `/teknisi/dashboard` |

Logout hanya tersedia melalui form `POST` dengan token CSRF dan dialog konfirmasi.

## Struktur Folder

```text
bkkbn_eticketing/
├── app/
│   ├── Config/          # Konfigurasi aplikasi dan database
│   ├── Controllers/     # Controller autentikasi, dashboard, profil, sistem
│   ├── Core/            # App, Router, Request, Response, View, Database
│   ├── Exceptions/      # Penanganan error global
│   ├── Helpers/         # Fungsi bantu
│   ├── Middleware/      # Auth, guest, dan role middleware
│   ├── Models/          # Base model dan model pengguna
│   ├── Services/        # Auth, session, dan logger
│   └── Views/           # Layout, halaman, error
├── bootstrap/           # Bootstrap aplikasi
├── config/              # Konfigurasi dan route
├── database/            # SQL dan migrasi
├── public/              # Front controller dan aset
├── storage/             # Log, cache, upload
├── .env.example         # Contoh konfigurasi
├── composer.json        # Dependensi
└── README.md
```

## Kendala Umum dan Solusi

### 1. "Dependensi belum terpasang"

Jalankan:

```cmd
composer install
```

### 2. "File .env belum tersedia"

Salin `.env.example` menjadi `.env`:

```cmd
copy .env.example .env
```

### 3. "Koneksi database gagal"

Periksa:

- Database `db_usulan_perbaikan` sudah dibuat;
- Kredensial di `.env` sudah benar;
- MySQL/MariaDB sedang berjalan.

### 4. Halaman 404 pada route

Pastikan:

- URL diakses melalui `public/`;
- Modul `mod_rewrite` Apache aktif;
- File `.htaccess` di `public/` tersedia.

## Upload Foto Kerusakan

- Foto disimpan di `storage/uploads/tickets/`, bukan di folder publik.
- Format yang diterima: JPG/JPEG, PNG, dan WEBP.
- Batas ukuran dan jumlah file dapat diatur melalui `UPLOAD_MAX_SIZE_MB` dan `UPLOAD_MAX_FILES`.
- Pastikan `upload_max_filesize`, `post_max_size`, dan `max_file_uploads` pada PHP tidak lebih kecil dari konfigurasi aplikasi.

## Status Proyek

Aplikasi telah selesai, lulus testing manual, dan dinyatakan siap digunakan pada lingkungan produksi. Perlindungan production mencakup validasi konfigurasi fail-closed, throttling login, session hardening, SRI CDN, deklarasi ekstensi PHP, serta pemeriksaan kesiapan server dan schema melalui `composer production-check`.

## Dokumentasi

Baca dokumentasi lengkap di folder `docs/`:

1. `docs/00-PROJECT-CONTEXT.md`
2. `docs/01-PRD-LENGKAP.md`
3. `docs/02-ARCHITECTURE.md`
4. `docs/03-DATABASE-DESIGN.md`
5. `docs/04-ROADMAP-FASE.md`
6. `docs/05-CODING-STANDARDS.md`
7. `docs/06-STATUS-PROJECT.md`
8. `docs/08-REVIEW-FASE-1.md`
9. `docs/23-PANDUAN-PENGGUNA-EMPAT-ROLE.md`
10. `docs/24-DEPLOYMENT-BACKUP-DAN-RECOVERY.md`
11. `docs/25-SKENARIO-BLACK-BOX-DAN-UAT.md`
12. `docs/26-CHECKLIST-BUKTI-BAB-IV.md`
13. `docs/27-DATA-AWAL-DAN-AKUN-PRODUKSI.md`
14. `docs/28-PRODUCTION-READINESS.md`
