# Catatan Pengujian

Sistem ini diuji dengan PHP 8.3 dan MariaDB 10.11 yang benar-benar dijalankan,
bukan sekadar diperiksa secara statis. Ringkasan berikut mencatat apa yang
sudah terbukti jalan dan apa yang belum, supaya tidak ada dugaan keliru saat
pemasangan.

## Sudah diverifikasi

**Sintaks** — 110 berkas PHP lolos `php -l` tanpa galat.

**Basis data** — 96 tabel terpasang bersih dari `01_schema.sql`; seed masuk
tanpa galat kunci asing.

**Model** — 26 pemanggilan langsung terhadap basis data sungguhan: tap RFID
(masuk, tap ulang, kartu tak dikenal), rekap absensi, pencatatan nilai,
hitung ulang, penyusunan rapor, peringkat, ekspor Dapodik, gamifikasi,
dan tiga jalur notifikasi.

**Halaman web** — seluruh rute GET ditelusuri dengan sesi login sungguhan
untuk delapan akun (superadmin, kepala sekolah, wali kelas, guru mapel,
tata usaha, pustakawan, dua siswa). Tidak ada galat PHP yang bocor ke halaman.

**Alur penuh yang dijalankan sampai tuntas:**

| Alur | Hasil |
|---|---|
| Modul ajar: susun → ajukan → setujui | Status berubah, catatan kepala sekolah tersimpan |
| E-rapor: input nilai → hitung → susun → terbit → cetak | Peringkat benar, halaman cetak lengkap |
| Ekspor Dapodik | CSV keluar dengan BOM UTF-8 dan pemisah titik koma |
| Ujian: kerjakan → koreksi otomatis → koreksi uraian → final | Nilai masuk rapor, poin dan notifikasi orang tua terkirim |
| Absensi RFID lewat HTTP | Tap tercatat, balasan dipotong 16 karakter untuk LCD |
| Tugas, literasi, permainan, pembaca e-book | Tersimpan, poin bertambah |
| Sirkulasi perpustakaan, tagihan, disposisi surat | Tersimpan dengan status yang benar |
| Projek P5: buat → nilai capaian → tercetak di rapor → tampil di API ortu | 6 baris capaian tersimpan, muncul di lembar cetak |
| Supervisi: isi instrumen → skor otomatis → notifikasi guru | Skor 90, predikat Amat Baik |
| Mutasi siswa pindah keluar | Status siswa dan keanggotaan kelas ikut berubah |
| Absensi per mapel | Tersimpan; siswa hadir di gerbang tapi alpa di kelas terdeteksi |
| 19 permainan pada 15 mata pelajaran | Semua termuat tanpa galat, semuanya bersoal |
| Kontrak 11 layar Flutter terhadap balasan API | 0 ketidakcocokan nama medan |
| Pemeriksa statis 16 berkas Dart | 0 temuan |
| 136 rute dipetakan ke method controller | 0 hilang |
| 20 endpoint POST yang belum pernah dijalankan | Semua tersimpan ke basis data |
| Sirkulasi perpustakaan pinjam lalu kembali | Eksemplar kembali berstatus TERSEDIA |
| Penilaian tugas oleh guru | Nilai 88 tersimpan dan masuk rekap nilai formatif |
| Pembayaran lintas orang tua | Ortu lain ditolak melihat, membayar, dan mengunggah bukti anak orang |
| Unggah bukti berupa skrip PHP dan gambar palsu | Keduanya ditolak; isi berkas diperiksa, bukan hanya ekstensinya |
| Konfirmasi pembayaran dua kali | Hanya satu baris pembayaran tercipta; nominal tidak berlipat |
| Yayasan mencoba menulis di lima modul | Semua 403; tidak ada data tercipta |
| Nominal kas nol dan negatif | Ditolak; nol transaksi bernilai ≤ 0 |
| Injeksi SQL, XSS, dan path traversal pada pencarian | Tidak ada yang tembus |
| Izin dipakai kode vs terdaftar di basis data | Nol selisih setelah perbaikan |
| Pendaftaran kartu RDM6300 dan normalisasi nomor | Kartu didaftarkan `0006168273`, ditap sebagai `6168273`, tetap dikenali |
| Blokir kartu hilang | Tap ditolak, tercatat sebagai KARTU_BLOKIR |
| Tap lewat pembaca USB desktop | Tercatat lewat perangkat maya USB-DESKTOP |
| Pengawasan ujian | Pelanggaran ke-2 menghentikan ujian; jawaban yang sudah diisi tetap dinilai 100; guru dapat notifikasi; siswa tidak bisa membuka ulang |
| Pemasangan dari nol pada basis data kosong | 96 tabel, keempat berkas SQL masuk tanpa galat, seluruh peran bersih |

**API wali murid** — 15 endpoint GET dan 5 POST diuji dengan token sungguhan.
Penjaga keamanan terbukti menolak: akses data anak orang lain, token palsu,
permintaan tanpa token, akun guru yang mencoba masuk lewat API orang tua,
dan kata sandi salah.

**Cron** — keempat skrip dijalankan sampai selesai tanpa galat.

## Cakupan modul

Seluruh tabel pada skema kini punya implementasi. Yang sebelumnya hanya
kerangka basis data dan sudah dilengkapi pada tahap ini: `kokurikuler`,
`kokurikuler_nilai`, `supervisi`, `absensi_mapel`, `mutasi_siswa`, dan
`dapodik_mapping`. Mesin permainan yang semula mendukung 5 tipe kini
mencakup kesepuluh tipe pada skema.

## Catatan perangkat keras

Firmware tersedia untuk dua jenis pembaca. Keduanya **belum dikompilasi maupun
diuji pada perangkat sungguhan** — sandbox pengujian tidak memiliki Arduino IDE
atau perangkat kerasnya. Yang sudah diuji adalah sisi servernya: endpoint tap
dipanggil lewat HTTP dengan muatan yang sama persis seperti yang dikirim
firmware, termasuk kasus kartu tak dikenal, kartu diblokir, tap ulang, dan
perangkat dengan kunci salah.

Yang perlu diperiksa langsung saat pemasangan: perilaku antrean luring di flash
ESP32, jarak baca antena, dan kecocokan format nomor kartu antara pembaca USB
yang dipakai mendaftarkan kartu dengan mesin gerbang.

## Belum diuji

- **Aplikasi Flutter** belum dikompilasi. Sandbox pengujian tidak memiliki
  Flutter SDK, jadi `mobile/` baru diverifikasi sebatas kesesuaian nama medan
  dengan balasan API. Jalankan `flutter analyze` sebelum rilis.
- **Firmware ESP32** belum dikompilasi maupun diuji di perangkat keras.
  Endpoint yang dipanggilnya sudah diuji lewat HTTP dengan muatan yang sama
  persis, tetapi perilaku antrean luring di flash perlu diuji langsung.
- **Fitur AI** dijalankan tanpa kunci API, sehingga yang teruji adalah jalur
  cadangannya. Jalur pemanggilan Anthropic perlu diuji dengan kunci sungguhan.
- **Beban banyak pengguna** belum diukur. Seed hanya berisi 3 siswa; sekolah
  dengan 300 siswa perlu diuji terutama pada halaman rekap dan penyusunan rapor
  satu kelas penuh.
- **Unggah berkas** baru diuji lewat pemeriksaan nama medan, bukan dengan
  mengunggah berkas sungguhan.

## Bug yang ditemukan dan diperbaiki selama pengujian

Dicatat agar terlihat kelas galat apa yang perlu diwaspadai bila menambah fitur.

1. Hash kata sandi di seed tidak sah — tidak ada satu pun akun demo yang bisa masuk
2. Bentrok nama variabel `$ta` antara layout dan controller pengaturan
3. Kepala sekolah tertolak dari seluruh modul perangkat ajar, padahal dialah
   yang menyetujui; ditambah kuerinya tidak menampilkan modul berstatus diajukan
4. 22 URL formulir dan `fetch` tidak cocok dengan rute — tombol simpan diam-diam 404
5. `AuthApi` memakai kolom `keterangan`, seharusnya `deskripsi` — login API gagal total
6. `bersih-berkala` memakai `rfid_log.created_at`, seharusnya `waktu`
7. Enum `jenjang_baca` dan `hasil` tidak cocok dengan skema
8. Kolom `file_materi` tidak ada; yang benar `file_lampiran`
9. Nama medan unggahan berbeda antara formulir dan controller
10. Jawaban uraian yang belum dikoreksi dihitung sebagai salah, dan nilai
    sementaranya langsung masuk rapor
11. Halaman koreksi uraian belum ada sama sekali, sehingga nilai ujian
    bersoal uraian tidak akan pernah final
12. Rute simpan mata pelajaran dan jadwal belum ada
13. Dashboard siswa membaca medan yang tidak dikirim kuerinya
14. Kolom `sync_dapodik.keterangan` tidak ada; yang benar `response_log`
15. Atribut `hidden` kalah oleh `style="display:grid"` inline — modal disposisi,
    pembayaran, dan pengumpulan tugas selalu tampil menutupi layar
16. Berkas statis tidak dilayani saat memakai server bawaan PHP, sehingga
    seluruh CSS gagal dimuat pada pengujian lokal
17. Kartu yang diblokir tetap diterima karena jalur cadangan `siswa.rfid_uid`
    melewati pemeriksaan status — pemblokiran jadi tidak ada gunanya
18. Zona waktu sesi MySQL tidak disamakan dengan zona waktu aplikasi, sehingga
    `CURDATE()` di SQL dan `date()` di PHP bisa berbeda hari
19. Berkas seed memaksa `USE simap_db`, sehingga sekolah tidak bisa memakai
    nama basis data lain
20. Layar profil aplikasi membaca medan `hari` dan `jam` untuk ekstrakurikuler,
    sedangkan API mengirim `jadwal` — jadwal ekskul tampil kosong di aplikasi
    orang tua
21. Endpoint penilaian tugas sudah ada dan benar, tetapi tidak ada satu pun
    formulir yang memanggilnya — guru tidak bisa menilai tugas sama sekali
22. Siswa pada data contoh tidak terdaftar sebagai anggota perpustakaan,
    sehingga sirkulasi peminjaman tidak dapat diuji maupun dipakai
23. Tabel `guru_mapel` tidak pernah terisi dan tidak ada layar untuk mengisinya,
    sehingga daftar mata pelajaran pada menu Perangkat Ajar selalu kosong dan
    guru tidak bisa menyusun Prota, ATP, maupun Modul Ajar
24. Kolom wajib `guru_mapel.kelas_id` terlewat pada kode maupun data contoh;
    `INSERT IGNORE` menelan galatnya sehingga kegagalan tidak terlihat
25. Akun yang tidak terhubung ke data guru menyimpan dokumen dengan
    `guru_id = 0`, ditolak kunci asing dan menampilkan jejak galat SQL kepada
    pengguna. Terjadi di enam tempat: prota, ATP, modul ajar, jurnal, bank soal,
    ujian, materi, dan tugas
26. `simpanPromes` tidak memeriksa kepemilikan sama sekali, sehingga guru bisa
    menimpa program semester milik rekannya hanya dengan menebak nomor prota
27. Kolom `modul_ajar.model_pembelajaran` hanya 80 karakter, terlalu pendek untuk
    isian sungguhan; galat basis data muncul di layar sebagai jejak teknis
28. Izin `master.jadwal.manage` dipakai tampilan tetapi tidak pernah terdaftar,
    sehingga hanya superadmin yang dapat mengatur jadwal pelajaran — kepala
    sekolah, tata usaha, dan operator tidak melihat formulirnya

Pola yang berulang: **ketidakcocokan nama kolom dan nilai enum**. Bila menambah
modul baru, periksa dulu skema dengan `SHOW COLUMNS` alih-alih mengandalkan
ingatan.
