think
16px
820px

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

flowchart TD U["Unit & integration (bun test / vitest)
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 --noEmit di masing-masing folder. Baseline master (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 ke pdftotext -layout.
  • Menambah sampel = taruh PDF + <basename>.expected.json sesuai konvensi nama di docs/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)

  1. cd backend && bunx tsc --noEmit dan cd frontend && bunx tsc --noEmit bersih.
  2. bun test backend + bun run test frontend hijau penuh (bukan hanya suite yang disentuh), termasuk regression D10 (§3c).
  3. Bila menyentuh prompt/grounding/harvest: jalankan eval §4; skor per sampel tidak turun dari baseline tanpa penjelasan tertulis di PR.
  4. Bila menyentuh schema Prisma: sertakan file migration asli (staging menjalankan migrate deploy; db push menyembunyikan migration yang hilang) + prisma generate (client stale = 500 pada enum baru).
  5. Uji manual minimal H1 + satu skenario asing (H3 atau SYARAT_ASING_CONTENT) pada UI hidup.