Dokumen Testing — Pendirian Yayasan (PENDIRIAN_YAYASAN)
Status: as-built 2026-08-18, mengikuti flow-pendirian-yayasan.md.
Baseline:master@cd80b348(merge PR #16) — suite test hijau penuh pada baseline ini.
Cakupan: unit/integration test otomatis, eval akurasi ekstraksi (golden set), seed demo UI, dan skenario uji manual end-to-end per rule.
1. Peta lapisan pengujian
rule, schema, classifier, context, projector, route"] --> E["Eval akurasi ekstraksi
scripts/eval-akta-yayasan.ts vs golden set"] E --> S["Seed demo UI
scripts/seed-yayasan-demo.ts"] S --> M["Uji manual end-to-end
upload PDF asli → Klasifikasi → Proses → Review → Submit"]
Prinsipnya: lapisan bawah murah dan deterministik (jalan di setiap perubahan); lapisan atas butuh layanan hidup (OCR/vLLM/SABH) dan sampel asli yang tidak di-commit (gitignored — berisi NIK/alamat).
2. Prasyarat lingkungan
| Kebutuhan | Untuk | Catatan |
|---|---|---|
| PostgreSQL Docker (port 5433) | test ber-DB + backend dev | cd backend && docker compose up -d |
| DB test | suite yang menyentuh Prisma | cd backend && bun run db:push:test (membuat ahu_ocr_test di 5433) |
PADDLE_OCR_URL (layanan PaddleOCR hidup) |
eval golden set untuk sampel SCAN | sampel born-digital cukup pdftotext -layout |
Endpoint vLLM (AKTA_TXN_CLASSIFIER_URL, Qwen) |
eval golden set (LLM read) | temperature 0, thinking off (model thinking wajib enable_thinking=false, kalau tidak hasilnya teks reasoning, bukan JSON) |
| SABH MySQL readonly | NAMA_AVAILABILITY live (seed demo + uji manual) |
tanpa ini rule tetap jalan tapi hasilnya degradasi/skipped sesuai koneksi |
Sampel docs/samples/yayasan/ |
eval + uji manual | PDF + .expected.json gitignored; manifest di README folder itu |
3. Test otomatis (jalan tanpa layanan eksternal)
Perintah:
cd backend && bun test
cd frontend && bun run test
Jalankan kedua suite penuh sebelum push, bukan hanya typecheck. Typecheck:
bunx tsc --noEmitdi masing-masing folder. Baselinemaster(PR #16) hijau penuh; jalankan penuh lagi setiap ada perubahan.
3a. Backend — inti flow Pendirian Yayasan
| File | Menguji |
|---|---|
src/flow-engine/rules/__tests__/yayasan-pendirian.test.ts |
Rule set D11 Yayasan: kekayaan (present/asing-min/nasional-min, angka-vs-terbilang), syarat asing present, required-fields, NIK format/TTL-match, rangkap organ, daftar non-overridable |
src/flow-engine/rules/__tests__/nirlaba-shared.test.ts |
3 rule bersama: AKTA_PRESENT, ORGAN_COMPLETENESS (FAIL), NAMA_AVAILABILITY (paritas pesan-nama; dependensi di-inject, bukan mock.module) |
src/flow-engine/rules/__tests__/yayasan-organ-identity.test.ts |
ORGAN_IDENTITY_COMPLETE: nama/identitas/jabatan kosong, KITAS dihitung identitas |
src/flow-engine/rules/__tests__/yayasan-syarat-asing-content.test.ts |
SYARAT_ASING_CONTENT: deteksi residence-permit vs kop Kemenlu, SKIPPED saat teks belum ada |
src/flow-engine/context/__tests__/yayasan-pendirian-context.test.ts |
buildYayasanPendirianContext: blob → ctx (organ, kekayaan, aktaMeta, syaratAsingText) |
src/flow-engine/__tests__/registry.test.ts |
Registrasi flow PENDIRIAN_YAYASAN (engine v2-generic, terminal, requiredDocs) |
src/schema/__tests__/akta-yayasan.test.ts |
Schema ekstraksi + normalisasi nilai |
src/services/__tests__/nirlaba-akta-classifier.test.ts |
Title tier: kepala "AKTA PENDIRIAN YAYASAN" (toleran titik/spasi/baris OCR), tak false-match ke akta PT, short-circuit |
src/services/__tests__/nirlaba-syarat-asing-classifier.test.ts |
detectSuratKemenlu / detectResidencePermit (fixture e-ITAS/e-ITAP nyata) |
src/services/__tests__/nirlaba-akta-extract.test.ts |
Grounding + kebijakan confidence (verbatim/derived/ungrounded 0.40), persist ExtractedField+BoundingBox |
src/services/__tests__/nirlaba-akta-retry.test.ts |
Vision retry: skor gejala, pemilihan halaman tersangka |
src/services/__tests__/nirlaba-nama-availability.test.ts |
Query pesan-nama: konsumable/kedaluwarsa/terpakai/terblokir/terdaftar |
src/services/__tests__/kekayaan-harvest.test.ts, akta-opening-harvest.test.ts |
Panen deterministik Pasal 5 & pembukaan akta |
src/services/__tests__/latin-confusables.test.ts |
Perbaikan glyph OCR |
src/lib/ (nik-birthdate via rule tests) |
Decode DDMMYY (+40 perempuan) dari NIK |
src/review/__tests__/yayasan-pendirian-review.test.ts |
Projector Smart Review: section, baris manual-fill (REQUIRED_READ_FIELD_KEYS), autolock |
src/routes/__tests__/yayasan-organ-edit.test.ts |
Dialog edit organ (koreksi roster utk ORGAN_RANGKAP/identitas) |
src/routes/__tests__/override-policy.test.ts |
Endpoint override menolak YAYASAN_NON_OVERRIDABLE_RULE_CODES |
src/routes/__tests__/klasifikasi-yayasan-wna-labels.test.ts, klasifikasi-syarat-asing-track.test.ts, submissions-upload-syarat-asing.test.ts, doc-type-in-flow.test.ts |
Taksonomi & track dokumen asing (Kemenlu, RESIDENCE_PERMIT) di route klasifikasi/upload |
src/routes/__tests__/submissions-infer-type.test.ts |
Inferensi PENDIRIAN_YAYASAN dari label classifier |
3b. Frontend
| File | Menguji |
|---|---|
src/lib/__tests__/yayasan-flow.test.ts |
Stepper YAYASAN_LABELS, status ladder terminal, navigasi flow |
src/components/yayasan/__tests__/OrganRosterSection.test.tsx |
Roster organ (3 slot, identitas, jabatan) |
src/components/klasifikasi/classification-board.test.tsx, src/pages/__tests__/KlasifikasiPage.*.test.tsx |
Board klasifikasi + override tipe dokumen |
src/store/__tests__/board-handoff.test.ts |
Handoff board → proses |
3c. Regression wajib (D10 — modul bersama)
Extractor/context/rule bersama dipakai Yayasan⇄Perkumpulan (dan flow perubahan). Setiap perubahan pada nirlaba-shared, organ-nirlaba, atau nirlaba-akta-extract wajib ikut menjalankan:
cd backend && bun test flow-engine/rules/__tests__/perkumpulan-pendirian.test.ts review/projectors/__tests__/perkumpulan-pendirian-review.test.ts flow-engine/rules/nirlaba-perubahan/
Catatan teknis suite:
- Jangan pakai mock.module bun — bocor lintas file test pada full run; inject dependensi (contoh pola: nirlaba-nama-availability). Gejala bocor: test merah pada full run tapi hijau saat file dijalankan sendirian — verifikasi dengan run terisolasi sebelum menyimpulkan regresi.
- Test upload harus pakai bytes unik per upload + reset cache permanent-failure per test; jangan feed buffer kosong ke jalur provider.
4. Eval akurasi ekstraksi (golden set)
Harness: backend/scripts/eval-akta-yayasan.ts — menjalankan prompt ekstraksi produksi (runNirlabaAktaExtractionWithRetry) terhadap semua PDF di docs/samples/yayasan/akta/ yang punya kembaran .expected.json, lalu skor field-by-field (normalisasi ringan; organ dicocokkan bebas-urutan by nama).
cd backend && bun scripts/eval-akta-yayasan.ts
- Laporan: tercetak + tertulis ke
backend/tmp/eval-akta-yayasan.md(gitignored). - Baseline 2026-08-14 (untuk deteksi regresi — skor baru tidak boleh turun tanpa penjelasan): TOTAL 401/422 field (95.0%) — JIMMYAN asing 88.3% (miss dominan: prefiks "YAYASAN", jabatan tanpa kata organ), 5026072251101253 asing 100%, NIAGAMAS asing 91.0%, nasional born-digital 100%, nasional scan 95.2%.
- Sampel scan butuh
PADDLE_OCR_URL; born-digital jatuh kepdftotext -layout. - Menambah sampel = taruh PDF +
<basename>.expected.jsonsesuai konvensi nama didocs/samples/yayasan/README.md, lalu jalankan ulang harness.
5. Seed demo UI (tanpa OCR/LLM hidup)
cd backend && bun scripts/seed-yayasan-demo.ts
Membuat 2 submission PENDIRIAN_YAYASAN READY (1 nasional + 1 asing) langsung dari golden samples: PDF disalin ke uploads/, ExtractedField diisi sesuai kontrak shape, dan rule set asli dijalankan (termasuk NAMA_AVAILABILITY live bila SABH terjangkau). Idempotent — rerun menghapus demo lama (tag originTransactionRef). Berguna untuk review UI Smart Review tanpa menunggu pipeline penuh.
6. Skenario uji manual end-to-end
Jalur baku: buka UI → buat pengajuan Pendirian Yayasan → Unggah → Klasifikasi → Proses & Periksa → Review & Submit → Selesai (terminal, read-only).
6a. Happy path
| # | Skenario | Bahan | Ekspektasi |
|---|---|---|---|
| H1 | Nasional born-digital | akta-yayasan_nasional_2026_5026071731101015.pdf (BOSS ACADEMY) |
Klasifikasi AKTA_PENDIRIAN_YAYASAN otomatis; ekstraksi penuh; KEKAYAAN_NASIONAL_MIN dinilai, rule asing SKIPPED; submit → Selesai |
| H2 | Nasional scan | akta-yayasan_nasional_2026_5026080735100393.pdf |
Sama dgn H1; amati confidence lebih rendah pada field hasil OCR (pensil muncul di bawah 0.95) |
| H3 | Asing lengkap | akta JIMMYAN + surat-kemenlu_asing_2026_5026010831100648.pdf |
SYARAT_ASING_PRESENT PASS; SYARAT_ASING_CONTENT PASS (kop Kemenlu terdeteksi); identitas organ paspor/KITAS diterima |
6b. Matriks pemicu per rule (uji negatif)
| Rule | Cara memicu | Ekspektasi |
|---|---|---|
AKTA_PRESENT |
Coba lanjut tanpa akta | FAIL hard-block; tidak ada tombol override yang efektif (endpoint menolak) |
ORGAN_COMPLETENESS |
Akta dgn organ tak terbaca (atau hapus anggota via edit organ sampai satu slot kosong) | FAIL; override tersedia (extraction-doubt) |
NAMA_AVAILABILITY |
(a) nama tak pernah dipesan; (b) reservasi kedaluwarsa/terpakai; (c) nama sudah terdaftar base=yayasan; (d) reservasi konsumable | (a-c) FAIL dgn alasan spesifik; (d) PASS. Override hanya saat confidence nama_* rendah |
KEKAYAAN_AWAL_PRESENT |
Akta JIMMYAN (Pasal 5 angka vs terbilang bertentangan) | WARNING menyebut kedua nilai; bentuk ANGKA yang dipakai flow |
KEKAYAAN_ASING_MIN |
Akta JIMMYAN (asing, angka Rp1.000.000) | FAIL < Rp100 juta; setelah operator koreksi nilai (pensil) → re-validasi bisa membalik hasil |
KEKAYAAN_NASIONAL_MIN |
Sampel/nilai nasional < Rp10 juta (edit nilai utk simulasi) | FAIL menyebut PP 63/2008 |
REQUIRED_FIELDS_PRESENT |
Scan buruk / field wajib null (mis. blank-kan nomor akta via simulasi) | WARNING menyebut field per nama + baris pensil kosong di section terkait; provinsi TIDAK pernah dituntut |
SYARAT_ASING_PRESENT |
Pengajuan asing tanpa dokumen Kemenlu | FAIL; upaya override DITOLAK (non-overridable) |
SYARAT_ASING_CONTENT |
Unggah residence-permit_asing_*.pdf sebagai SURAT_PERTIMBANGAN_KEMENLU |
WARNING "terbaca seperti residence permit"; remedinya re-map tipe dokumen ke RESIDENCE_PERMIT → warning hilang |
ORGAN_IDENTITY_COMPLETE |
Sampel dgn identitas hilang (kasus lapangan CICILIA/HO, JUNGCHANHEE) atau kosongkan jabatan via edit | WARNING menyebut slot+nama; lengkapi manual → PASS |
ORGAN_NIK_TTL_MATCH |
Sampel dgn NIK-vs-TTL mismatch (typo akta) | WARNING menyebut anggota; tak pernah FAIL |
ORGAN_NIK_FORMAT |
Sampel dgn NIK 15/17 digit (OLINKA 15-digit di BOSS ACADEMY; 17-digit di sampel asing) | WARNING menyebut jumlah digit |
ORGAN_RANGKAP |
Akta dgn baris "Pendiri" ikut terbaca sebagai Pembina (kasus KHOIRUL WAFA) | WARNING; koreksi via tabel Organ → PASS, atau Override bila akta memang menuliskannya |
6c. Klasifikasi & dokumen
| # | Skenario | Ekspektasi |
|---|---|---|
| K1 | Unggah akta PT ke pengajuan yayasan | Title tier nirlaba TIDAK match; jatuh ke jalur PT; AKTA_PRESENT yayasan tetap menuntut akta yayasan |
| K2 | Kepala akta dgn noise OCR ("AKTA. PENDIRIAN YAYASAN", header SALINAN/NOMOR di atasnya) | Tetap terklasifikasi AKTA_PENDIRIAN_YAYASAN |
| K3 | Override tipe dokumen di board | Tipe manual menang; proses ulang memakai tipe baru |
| K4 | Scan rusak (halaman gelap/miring) | Vision retry jalan otomatis; field hasil retry tetap di bawah autolock |
6d. Review, override, terminal
| # | Skenario | Ekspektasi |
|---|---|---|
| R1 | Field confidence ≥ 0.95 | Terkunci otomatis (tanpa pensil); field turunan (0.75) & ungrounded (0.40) selalu editable |
| R2 | Override FAIL biasa (mis. KEKAYAAN_ASING_MIN) |
Wajib isi alasan; tercatat; submit terbuka |
| R3 | Override AKTA_PRESENT/SYARAT_ASING_PRESENT |
Ditolak endpoint; FE tidak menawarkan |
| R4 | Submit sukses | Status Selesai; read-only; tidak ada write-back ke SABH |
| R5 | Unggah ulang akta pada pengajuan yang sudah berjalan | Akta lama beserta PDF-nya ikut terganti (tidak ada akta ganda); proses ulang jalan otomatis. Catatan: tidak ada jalur "hapus akta" di flow ini — penggantian selalu lewat re-upload |
7. Definisi selesai (checklist rilis perubahan pada flow ini)
cd backend && bunx tsc --noEmitdancd frontend && bunx tsc --noEmitbersih.bun testbackend +bun run testfrontend hijau penuh (bukan hanya suite yang disentuh), termasuk regression D10 (§3c).- Bila menyentuh prompt/grounding/harvest: jalankan eval §4; skor per sampel tidak turun dari baseline tanpa penjelasan tertulis di PR.
- Bila menyentuh schema Prisma: sertakan file migration asli (staging menjalankan
migrate deploy;db pushmenyembunyikan migration yang hilang) +prisma generate(client stale = 500 pada enum baru). - Uji manual minimal H1 + satu skenario asing (H3 atau
SYARAT_ASING_CONTENT) pada UI hidup.