think
16px
820px

Blackbox Testing — Laporan RUPS Tahunan (PT)

  • Domain: PT
  • Fitur: Laporan RUPS Tahunan (Pelaporan RUPS Tahunan, UUPT Pasal 66-68)
  • Role/aktor: notaris (input & finalisasi), admin (akses menyeluruh). Tidak ada tahap verifikator (flow terminal self-service).
  • Tanggal uji: 2026-08-19
  • Penguji (sesi): Supervisor PT
  • Build/commit: 63c40a17

1. Ringkasan fitur

Laporan RUPS Tahunan memproses paket dokumen laporan tahunan perseroan (Akta atau Risalah RUPS Tahunan sebagai dokumen utama, ditambah laporan keuangan dan sejumlah lampiran) untuk mencatatkan pelaporan tahunan ke SABH. Notaris mengunggah paket lewat papan Klasifikasi, sistem menjalankan OCR, ekstraksi, dan pencarian perseroan pada registri, lalu menampilkan halaman tinjauan berisi identitas perseroan, field akta, pilihan tahun laporan dan jenis audit, data akuntan publik, serta hasil validasi. Notaris memilih tahun laporan dan jenis audit, menyetujui tiap bagian wajib, lalu mengirim lewat tombol Kirim Laporan (Final). Flow ini terminal: begitu dikirim, statusnya langsung COMPLETED tanpa antrean verifikator, karena pelaporan tahunan adalah pengajuan administratif dan SABH tidak membuat baris verifikasi untuk alur ini. Ini adalah tenant pertama yang memakai mesin generic v2 (engine: v2-generic).

2. Full workflow

2.1 Diagram state

stateDiagram-v2 [*] --> CREATED CREATED --> EXTRACTING: POST /start EXTRACTING --> AWAITING_COMPANY_SELECTION: lookup perseroan tidak menemukan 1 kecocokan pasti AWAITING_COMPANY_SELECTION --> VALIDATING: pilih perseroan (select-company) EXTRACTING --> VALIDATING: 1 kecocokan pasti langsung lanjut VALIDATING --> READY: aturan validasi dijalankan READY --> COMPLETED: Kirim Final (atestasi + bagian wajib disetujui + tidak ada FAIL tersisa + WARNING diakui) COMPLETED --> [*] EXTRACTING --> ERROR: kegagalan OCR/ekstraksi akta

2.2 Sequence (aktor - sistem)

sequenceDiagram actor N as Notaris participant FE as Frontend participant BE as Backend :47014 participant OCR as OCR/LLM participant REG as Registri SABH (read-only) N->>FE: Unggah paket (akta + laporan keuangan + lampiran) di /klasifikasi FE->>BE: POST /api/klasifikasi/upload + /classify (per berkas) OCR-->>BE: AKTA_RUPS_TAHUNAN / LAPORAN_KEUANGAN / OTHER FE->>BE: POST /api/submissions (infer LAPORAN_RUPS_TAHUNAN) FE->>BE: POST /api/submissions/:id/start BE->>OCR: ekstraksi field akta + focused pass laporan keuangan BE->>REG: companyLookup (nama_perseroan + nomor_sk) REG-->>BE: kandidat kecocokan alt tidak ada kecocokan pasti tunggal BE-->>FE: status AWAITING_COMPANY_SELECTION N->>FE: pilih perseroan FE->>BE: POST /api/perubahan/select-company/:id end BE->>BE: jalankan aturan validasi, status READY FE->>BE: GET /api/laporan-rups/submissions/:id/review-data (poll) N->>FE: pilih tahun laporan + jenis audit, konfirmasi field, setujui bagian FE->>BE: PUT /tahun-laporan, PUT /jenis-audit, POST /sections/:key/approve N->>FE: Klik Kirim Final, akui tiap WARNING FE->>BE: POST /api/laporan-rups/submissions/:id/submit BE-->>FE: { status: COMPLETED, rupsSubmittedAt }

2.3 Peta route & UI

Langkah Route Komponen Elemen interaktif utama Selector
Unggah & klasifikasi paket /klasifikasi KlasifikasiPage dropzone/file input, papan doc-type (assign lampiran) input[type=file], tambah-dokumen-input
Ekstraksi (step 2) /laporan-rups/:id/extraction LaporanRupsExtractionPage auto-start pipeline, progres (tanpa testid stabil)
Tinjauan (step 3) /laporan-rups/:id/review LaporanRupsReviewPage pilih tahun laporan, radio jenis audit, konfirmasi field akta, setujui bagian, override FAIL, input akuntan publik, tombol Kirim Final, dialog deklarasi tombol berbasis teks (tanpa testid stabil)
Status (step 4) /laporan-rups/:id/status LaporanRupsStatusPage ringkasan tercatat, kembali ke dashboard (tanpa testid stabil)

3. Prasyarat & data uji

ID data Tipe Berkas Deskripsi Ekspektasi sistem
D-TW Positive paket tidak_wajib_audit/ (akta_notaris + laporan_keuangan) Paket non-audit, 2 dokumen scan asli Terklasifikasi LAPORAN_RUPS_TAHUNAN, mencapai READY, jalur kirim sampai COMPLETED
D-WA Positive paket wajib_audit/ (akta + 6 lampiran) Paket wajib audit, 7 dokumen scan asli Terklasifikasi LAPORAN_RUPS_TAHUNAN, mencapai READY; AKUNTAN_PUBLIK_REQUIRED aktif saat WAJIB_AUDIT
D-WAN Negative (varian D-WA) paket wajib audit tanpa data akuntan publik Set WAJIB_AUDIT tanpa mengisi akuntan AKUNTAN_PUBLIK_REQUIRED FAIL; kirim terblokir karena bagian akuntan-publik belum disetujui

Catatan data uji: berkas adalah scan asli (bergitignore) di e2e/data/real-intake/pt/laporan_rups/. Karena scan, mutasi berbasis text-layer (pdf-factory) tidak dipakai; negative case digali lewat variasi jenis audit dan kelengkapan data akuntan. Bukti tersimpan di e2e/artifacts/laporan-rups/ (results.json + 3 screenshot UI).

4. Matriks skenario uji

ID Tipe Lapisan Langkah ringkas Ekspektasi Hasil aktual Status Bukti
TC-01 Positive API Unggah paket D-TW, klasifikasi, submission, start, poll Terklasifikasi AKTA_RUPS_TAHUNAN (0.9992), type LAPORAN_RUPS_TAHUNAN, akhirnya READY Sesuai: akta 0.9992; paket park di AWAITING_COMPANY_SELECTION lalu READY setelah pilih perseroan PASS results.json (TW)
TC-02 Positive API Poll status paket D-TW Sampai READY (2 dokumen) Sesuai: READY, 2 dokumen, 8 hasil validasi PASS results.json
TC-03 Gate API Submit sebelum atestasi & persetujuan bagian Ditolak 400 SECTIONS_UNAPPROVED (bagian wajib belum disetujui dievaluasi lebih dulu) PASS results.json (gate_before_attestation)
TC-04 Gate API Submit saat FAIL masih berdiri (setelah atestasi + setujui bagian) 422 VALIDATION_FAILED Sesuai: failing=[RUPS_AKTA_FIELDS_PRESENT] PASS results.json (gate_with_fails)
TC-05 Gate API Override RUPS_AKTA_FIELDS_PRESENT dengan alasan Boleh (overridable) 200 OK PASS results.json (overrideOutcomes)
TC-06 Positive API Set NON_AUDIT + tahun valid, konfirmasi field, setujui bagian, override FAIL, akui WARNING, submit COMPLETED Sesuai: {submitted:true, status:COMPLETED} PASS results.json (finalSubmit)
TC-07 Positive API Unggah paket D-WA (7 dokumen), poll READY Sesuai: READY, 7 dokumen PASS results.json (WA)
TC-08 Positive API Set WAJIB_AUDIT tanpa data akuntan AKUNTAN_PUBLIK_REQUIRED FAIL Sesuai: FAIL "belum lengkap: nama_akuntan_publik, tanggal_izin_akuntan_publik" PASS results.json (akuntanRuleWajibNoData)
TC-09 Negative API Submit wajib audit tanpa isi akuntan & tanpa setujui bagian akuntan Terblokir 400 SECTIONS_UNAPPROVED missingSections=[akuntan-publik] PASS results.json (negative_submit_wajib_missing_akuntan)
TC-10 Positive API Isi data akuntan publik + setujui bagian akuntan AKUNTAN_PUBLIK_REQUIRED PASS Sesuai: PASS "Data akuntan publik lengkap" PASS results.json (akuntanRuleWajibWithData)
TC-11 Positive API Cek AKUNTAN_IZIN_FORMAT dari laporan keuangan asli WARNING untuk format tidak AP.xxxx, PASS untuk AP.1234 Sesuai: izin registri KAP asli "01308/..." WARNING; input "AP.1234" PASS PASS results.json (izinFormat)
TC-12 Positive UI Deep-link /laporan-rups/:id/review saat READY Halaman render, tombol Kirim Final disabled Sesuai: header + semua bagian tampil, tombol disabled PASS ui-review-gate.png
TC-13 Gate UI Setelah atestasi + setujui bagian + override FAIL, buka review Tombol Kirim Final enabled, dialog deklarasi muncul Sesuai: enabled, dialog "Kirim Pelaporan RUPS Tahunan" tampil PASS ui-submit-dialog.png
TC-14 Positive UI Buka review submission COMPLETED Redirect ke status "Laporan Tahunan Tercatat" Sesuai: redirect ke /status, teks final tampil PASS ui-status-completed.png

Ringkasan validasi paket D-TW saat READY: 2 FAIL (RUPS_AKTA_FIELDS_PRESENT, AKUNTAN_PUBLIK_REQUIRED sebelum atestasi jenis audit di-set), 3 PASS (TAHUN_LAPORAN_VALID, OLD_DATA_CONSISTENCY, PERSEROAN_STATE), 7 SKIPPED, 1 WARNING (RUPS_LAMPIRAN_COMPLETENESS). Setelah set NON_AUDIT, AKUNTAN_PUBLIK_REQUIRED menjadi SKIPPED sehingga hanya RUPS_AKTA_FIELDS_PRESENT yang perlu di-override.

5. Cakupan UI (semua yang diakses user)

Route/Elemen Diuji? Perilaku benar? Catatan
/klasifikasi unggah paket Ya (via API drive) Ya Klasifikasi menghasilkan AKTA_RUPS_TAHUNAN / LAPORAN_KEUANGAN; lampiran perlu assign manual di papan (lihat OBS-2)
/laporan-rups/:id/extraction Tidak (dilewati via API) - Auto-start pipeline; belum ada testid stabil (rekomendasi)
/laporan-rups/:id/review render Ya Ya Identitas Perseroan, Akta, Tahun & Jenis Audit, Akuntan Publik, Lampiran, Hasil Validasi semua tampil
Pilih tahun laporan (dropdown) Ya (API) Ya Opsi dari server-anchored window (createdAt-10..-1), bukan jam browser
Radio jenis audit (WAJIB/NON) Ya (API) Ya Membalik required bagian akuntan-publik di gate
Tombol Setujui Bagian Ya (API) Ya Baris eksplisit, bukan turunan konfirmasi field
Tombol Kirim Final (gate) Ya Ya disabled saat atestasi belum lengkap / FAIL berdiri / bagian belum disetujui
Dialog deklarasi + ack WARNING Ya Ya Deklarasi kebenaran data + centang tiap WARNING wajib
/laporan-rups/:id/status Ya Ya "Laporan Tahunan Tercatat", teks final, tanpa timeline verifikator
Panel verifikator N/A - Tidak ada (flow terminal self-service)

6. Temuan bug & perbaikan

ID bug Severity Ringkas Reproduksi Ekspektasi Aktual Screenshot Rekomendasi perbaikan
OBS-1 Med (ekstraksi) Field akta RUPS tahunan kosong dari scan asli Unggah paket D-TW/D-WA, buka review-data nomor_akta & tanggal_akta terekstrak akta.fields kosong ([]) meski extractionStatus DONE; di paket D-WA akta bahkan extractionStatus ERROR. RUPS_AKTA_FIELDS_PRESENT FAIL results.json (TW.aktaFields, WA classifiedDocs) Akta RUPS tahunan menumpang extractor "perubahan" (overrideByClassifiedType). Untuk scan asli extractor ini tidak menghasilkan field, sehingga notaris selalu harus override FAIL wajib SABH. Selidiki prompt/skema ekstraksi khusus akta RUPS tahunan atau retry ekstraksi
OBS-2 Med (desain) Lampiran tidak pernah terisi otomatis Unggah lampiran (kegiatan/TJSL/pengawasan/dll) Slot lampiran terisi setelah klasifikasi Klasifikasi melabeli lampiran sebagai AKTA_RUPS_TAHUNAN atau OTHER; label halus LAMPIRAN_* tidak pernah diproduksi classifier, semua 6 slot tetap kosong results.json (lampiranSlots) Sesuai desain (label halus adalah assignment manual di papan doc-type), tetapi berarti upgrade "wajib audit = 7 dokumen" tidak dapat dipenuhi lewat unggah saja tanpa remap manual. RUPS_LAMPIRAN_COMPLETENESS hanya WARNING sehingga tidak memblokir. Pertimbangkan classifier lampiran atau petunjuk assign yang jelas
OBS-3 Low (reliability) Kecocokan perseroan tidak pasti untuk data asli Unggah paket dengan perseroan nyata Idealnya 1 kecocokan pasti Paket park di AWAITING_COMPANY_SELECTION; diselesaikan lewat select-company manual. Untuk D-WA registri malah menandai PT terblokir (PERSEROAN_STATE FAIL "Pemblokiran karena dibuka sementara untuk akses perubahan dirkom") results.json (WA.validations) Wajar untuk registri read-only lokal; bukan cacat. Catat bahwa PERSEROAN_STATE bisa FAIL nyata dan (per kode) dapat di-override sebelum submit
OBS-4 Low (UI/uji) Tidak ada data-testid stabil di halaman laporan RUPS Tulis uji UI Selector stabil Uji UI bergantung pada teks tombol/heading screenshots Tambah data-testid pada tombol Kirim Final, dialog deklarasi, dan banner status untuk uji yang tahan perubahan teks

Catatan urutan gate (bukan bug): submit route mengevaluasi persetujuan bagian sebelum atestasi tahun/jenis. Saat mencoba submit tanpa apa pun, kode yang muncul lebih dulu adalah SECTIONS_UNAPPROVED, bukan ATTESTATION_INCOMPLETE. Keduanya benar sebagai gate; hanya urutan pesan yang perlu diketahui saat membaca error.

7. Ringkasan & rekomendasi

  • Total skenario: 14 (PASS 14 / FAIL 0). Semua skenario API dan UI lolos.
  • Cakupan UI: 8 dari 9 elemen inti diuji langsung di browser (extraction step dilewati via API; sisanya tercakup). Route review, dropdown tahun, radio jenis audit, gate Kirim Final, dialog deklarasi, dan status terminal semua terverifikasi.
  • Bug: High 0, Med 2 (OBS-1 ekstraksi field akta kosong, OBS-2 lampiran perlu assign manual), Low 2 (OBS-3, OBS-4).
  • Mekanisme finalisasi: route sendiri POST /api/laporan-rups/submissions/:id/submit (bukan finalize engine generik). Gate berurutan: atestasi tahun+jenis audit, persetujuan bagian wajib (akuntan-publik ikut wajib saat WAJIB_AUDIT), checkFailGate (block-with-override, envelope 422 VALIDATION_FAILED), lalu deklarasi + akui setiap WARNING, dalam satu transaksi ke COMPLETED. COMPLETED tercapai (terbukti API dan UI) tanpa tahap verifikator.
  • Logika kewajiban audit terbukti benar: NON_AUDIT membuat AKUNTAN_PUBLIK_REQUIRED SKIPPED dan bagian akuntan-publik tidak wajib disetujui; WAJIB_AUDIT mengaktifkan FAIL saat data akuntan (dokumen laporan keuangan + nama + nomor izin + tanggal izin) belum lengkap dan menjadikan bagian akuntan-publik wajib disetujui. Persyaratan dokumen lampiran (5 lampiran naik jadi wajib saat wajib audit) diformalkan di papan doc-type, tetapi RUPS_LAMPIRAN_COMPLETENESS hanya WARNING sehingga tidak memblokir submit.
  • Kuorum RUPS tidak divalidasi untuk alur ini (dikonfirmasi di kode: RUPS_TAHUNAN_RULE_SET sengaja tidak menyertakan RUPS_ATTENDANCE_QUORUM; pelaporan tahunan adalah pengajuan administratif, bukan keputusan voting).
  • Rekomendasi prioritas: (1) perbaiki ekstraksi field akta RUPS tahunan agar nomor & tanggal akta terisi tanpa override (OBS-1); (2) sediakan classifier atau alur assign lampiran yang jelas agar upgrade wajib-audit dapat dipenuhi (OBS-2); (3) tambah data-testid untuk uji UI yang stabil (OBS-4).
  • Gap/keterbatasan: field akta tidak terekstrak dari scan asli sehingga uji berbasis nilai field (mis. TAHUN_BUKU_ORDERING, RUPS_ANNUAL_WINDOW yang butuh tanggal_rups) tidak dapat dibuktikan positif dari data ini (semuanya SKIPPED karena tanggal_rups tidak terbaca). Pencocokan perseroan memakai registri SABH read-only sehingga hasil bergantung data registry nyata.