Usulan Implementasi: Perbaikan Yayasan
Tanggal: 2026-08-24 · Branch: dev/5 · Status: templat sudah dikerjakan
dan diselaraskan dengan katalog (belum di-commit); jalur penerbitan nirlaba belum
tersambung
Revisi 5. Templat penerbitan sudah dibangun dan diuji, sesudah ditemukan bahwa
templat PT yang dipakai selama ini rusak. Daftar bagian nirlaba kini bersandar data
perkumpulan, bukan hanya yayasan. Perubahan tiap revisi dicatat di §11.
1. Ringkasan
Alur Perbaikan Yayasan yang ada sekarang tidak bisa dipakai sama sekali. Bukan
kurang rapi, bukan menyimpang sedikit: tidak ada satu pun permohonan yang bisa
diselesaikan, karena sistem menunggu dokumen yang tidak pernah bisa dibuat.
Yang perlu diganti bukan namanya, melainkan bentuk datanya: dari "satu keadaan
entitas utuh" menjadi "daftar koreksi per kategori". Uji lengkapnya di §3.
Kabar baiknya, sebagian besar yang sudah dibangun tetap terpakai, dan Perbaikan
Data PT sudah punya persis pola yang kita butuhkan.
Revisi ini juga bersandar pada data nyata: 2.114 permohonan perbaikan Yayasan di
2025 dan 2026, yang membalik urutan kerja yang saya usulkan sebelumnya (§7.4).
Tambahan revisi 5. Templat penerbitannya sudah dibangun dan diuji, tiga berkas
terpisah untuk PT, Yayasan, dan Perkumpulan. Pekerjaan itu dimulai dari temuan tak
terduga: templat PT yang dipakai selama ini rusak sejak 10 Juli, empat bagian
terbit kosong dan satu mencetak kata "undefined" ke surat bermaterai, tanpa satu pun
error (§9.1). Itu sudah diperbaiki dan dikunci tes kontrak. Yang belum ada:
jalur penerbitan surat nirlaba, yang masih menunggu §5 langkah 2 (§9.4).
2. Temuan utama: alurnya buntu
2.1 Dokumen yang diminta tidak ada
Flow menuntut AKTA_PERBAIKAN_YAYASAN. Dokumen itu tidak ada di SABH:
grep -rin "akta_perbaikan|akta perbaikan" --include=*.php → 0 hasil
Yang diminta FormPerbaikanData.php hanya tiga: Surat Permohonan (step 2),
Surat Pernyataan (step 3), dan lampiran pemindaian (opsional). Tidak ada akta.
Masuk akal, karena perbaikan justru mengoreksi nomor_akta dan tanggal_akta
akta lama, bukan menerbitkan akta baru.
Notaris tidak punya "Akta Perbaikan Yayasan" untuk diserahkan.
2.2 Gerbangnya tidak bisa dilewati
AKTA_PRESENT berstatus FAIL kalau dokumen itu tidak ada, dan di
routes/nirlaba-perbaikan.ts:142:
const NON_OVERRIDABLE = new Set(["AKTA_PRESENT"]);
FAIL-nya tidak bisa di-override. Submit mengembalikan 409 selamanya.
2.3 Dari mana asalnya
Dua commit, penulis sama, hari sama, selisih 46 menit:
| Waktu | Commit | Isi |
|---|---|---|
| 15:15 | 294c8c3a |
Komentar skema: "Form/carrier-driven, NOT an akta flow (primaryAkta null)" |
| 16:01 | 5128017c |
Implementasi: primaryAkta: AKTA_PERBAIKAN_YAYASAN, sekaligus menciptakan tipe dokumen itu + migrasi 20260813140000 |
Pesan commit jam 16:01 tidak mengutip satu pun sumber SABH, padahal commit nirlaba
lain di repo ini selalu menyebut berkas dan barisnya. Klaim lain di commit yang
sama, "TERMINAL (a correction never needs Menteri approval)", juga keliru.
Kemungkinan besar kekeliruannya bermula dari kolom ini di PerbaikanData.php:
path_salinan_akta_pendirian_atau_perubahan
Akta memang diterima SABH, tetapi sebagai lampiran berupa salinan akta lama,
bukan dokumen utama, dan bukan "akta perbaikan".
3. Apakah cukup ganti nama saja?
Pertanyaan yang wajar: kalau AKTA_PERBAIKAN_YAYASAN sebenarnya memang surat
pernyataan, hanya salah nama, bukankah cukup diganti namanya?
Tidak cukup, dan hasilnya justru lebih berbahaya daripada buntu.
3.1 Flow-nya tidak sekadar memberi label
context/nirlaba-perbaikan-context.ts membaca berkas itu sebagai akta:
const { uploadedDocTypes, raw } = await readNirlabaAkta(submissionId, aktaType);
const after = yayasanAktaToState(raw as AktaYayasanData); // ← skema akta yayasan
Hasilnya after: NirlabaEntityState, yaitu keadaan entitas utuh (nama, nama
singkat, kedudukan, organ), yang lalu dibandingkan dengan data lama dari SABH.
Akta memang menyatakan ulang seluruh entitas. Surat pernyataan perbaikan tidak.
Surat itu hanya memuat kategori yang dikoreksi.
3.2 Contoh kegagalannya
Misalkan notaris hanya mengoreksi NPWP. Suratnya berisi satu bagian:
KOREKSI NPWP, lama 01.234..., baru 02.345...
membaca dengan skema AKTA"] B --> C["after = hampir seluruhnya null
(nama, kedudukan, organ tidak ada di surat)"] C --> D["identityChanges(old, after)
tanpa penjaga null"] D --> E["PASS: 'Perubahan terdeteksi:
Nama, Nama Singkat, Provinsi, Kabupaten/Kota'"] E --> F["NPWP, satu-satunya yang dikoreksi,
tidak diperiksa sama sekali"]
Perbandingannya memang tanpa penjaga null:
const cmp = (a, b, label) => { if ((a ?? null) !== (b ?? null)) changed.push(label); };
Jadi old.nama = "YAYASAN NURUS SYURO" lawan after.nama = null terbaca sebagai
"Nama berubah".
Hasil akhirnya: rule PASS, sambil melaporkan empat perubahan yang tidak pernah
diminta, dan mendiamkan satu-satunya yang diminta. Buntu setidaknya kelihatan;
ini tidak.
3.3 Cakupannya juga tidak memadai
identityChanges hanya melihat empat field: nama, nama singkat, provinsi,
kabupaten. Dari tujuh kategori Yayasan:
| Kategori | Tercakup? |
|---|---|
tempat_kedudukan_alamat |
sebagian (provinsi + kabupaten saja) |
npwp_ |
tidak |
nomor_akta |
tidak |
tanggal_akta |
tidak |
kegiatan |
tidak |
pendiri |
tidak |
organ |
tidak |
Sekalipun ekstraksinya sempurna, rule ini tidak bisa melihat enam dari tujuh.
3.4 Jadi apa yang bertahan
Bukan seluruhnya diganti. Yang tetap terpakai:
| Bertahan | Alasan |
|---|---|
entityFoundRule |
mencari badan hukum di SABH, benar untuk perbaikan |
readOldData + lookup SABH |
benar dan tetap dibutuhkan |
Rangka route (lookup, start, :id/document, :id/submit) |
bentuknya sudah tepat |
| 5 halaman frontend | tetap dipakai |
nirlaba-perbaikan-fields.ts |
7 kategori, sudah persis SABH |
Yang harus berubah:
| Berubah | Dari | Ke |
|---|---|---|
| Context builder | blob akta ke NirlabaEntityState |
kumpulan koreksi per kategori |
dataActuallyChangedRule |
diff identitas 4 field | cakupan 7 kategori |
| Penyimpanan | tidak ada padanan nirlaba | PerbaikanCorrection hanya milik PT |
aktaPresentRule |
AKTA_PERBAIKAN_YAYASAN |
surat pernyataan |
4. Model yang benar
4.1 Alur SABH
| Step | Isi | Wajib |
|---|---|---|
| 1 | nama, nomor, tgl_sksp, no_voucher |
ya |
| 2 | Surat Permohonan (templat 132), unduh, tanda tangan, unggah | ya |
| 3 | Centang kategori + Surat Pernyataan (templat 131/106), unduh, tanda tangan, unggah | ya |
| 4 | Selesai |
Lalu verifikasi dua tingkat: DITERIMA_STAFF lalu DITERIMA_KASI, dengan
cabang DITOLAK_STAFF, DITOLAK_KASI, dan REVISI_PERBAIKAN. Di
edit_badan_hukum_yayasan.php semua field disabled kecuali kategori yang
dicentang.
Tujuh kategori Yayasan, terverifikasi di FormPerbaikanData.php:46-54:
npwp_, tempat_kedudukan_alamat, nomor_akta, tanggal_akta, kegiatan,
pendiri, organ. Tanpa email/telepon, itu khusus Perseroan.
4.2 Perbaikan PT kita sudah punya jalur tanpa unggahan
createPerbaikanFromSuratKeterangan melakukan:
- buat
Submission(PERBAIKAN_DATA_PT, status=READY) - salin 13 baris koreksi langsung dari Surat Keterangan
- lampirkan PDF hasil terbitan sebagai
documentSource=GENERATED - jalankan cross-validation seketika
- lewati seluruh tahap OCR, karena datanya sudah ada
PERBAIKAN_DATA_PT punya requiredDocs: [] dan rules: [], jadi tidak ada
gerbang dokumen sama sekali. Pemohon mengetik data, sistem yang menerbitkan surat.
centang kategori, isi nilai"] --> B["Sistem terbitkan
Surat Keterangan"] B --> C["Permohonan dibuat
status READY"] C --> D["Validasi silang"] D --> E["Verifikator"] B -.->|"PDF terlampir
documentSource=GENERATED"| C
Halaman generator nirlaba kita sudah mengumpulkan persis data itu. Yang belum
ada hanya sisi backend, seperti tertulis di docstring-nya sendiri: "backend
persistence + PDF generation ('Terbitkan') come in a later phase."
4.3 Nama dokumennya
| Istilah | Apa sebenarnya |
|---|---|
| Surat Keterangan Perbaikan | nama kita untuk surat yang kita susun |
SURAT_PERNYATAAN_PERBAIKAN |
tipe dokumennya setelah menempel ke permohonan |
srtPernyataan |
nama SABH untuk artefak yang sama |
AKTA_PERBAIKAN_YAYASAN |
karangan, tidak ada di SABH |
Tiga yang pertama adalah benda yang sama.
5. Irisan minimal yang membuatnya bisa dipakai
Dua langkah.
Langkah 1 — Ganti bentuk data, bukan namanya
Ubah masukan context builder: dari blob akta yang diurai jadi NirlabaEntityState,
menjadi kumpulan koreksi per kategori. Ikut berubah: dataActuallyChangedRule
supaya mencakup tujuh kategori, penyimpanan koreksi (belum ada padanannya untuk
nirlaba), dan tipe dokumen yang dicari aktaPresentRule.
Lewat jalur "Terbitkan" beban langkah ini jauh berkurang, karena koreksinya sudah
terstruktur sejak pemohon mengetiknya, tidak perlu diurai dari dokumen.
Langkah 2 — Bangun "Terbitkan" di backend
Meniru createPerbaikanFromSuratKeterangan: simpan draft, susun surat dari
templat, buat permohonan READY, lampirkan sebagai GENERATED, jalankan validasi.
Setelah dua langkah ini, Perbaikan Yayasan bisa dibuat dan diselesaikan tanpa
pemohon mengunggah dokumen apa pun.
6. Sesudah itu (tidak menghalangi)
| Tahap | Isi | Catatan |
|---|---|---|
| Verifikator | Ubah submit dari COMPLETED ke antrean verifikator, dua tingkat |
Sesuai SABH. Perlu diketahui sebelum demo: perbaikan tidak lagi selesai seketika |
| Review projector | Isi PERBAIKAN_YAYASAN: null dengan tampilan per kategori |
Preseden ada di VerifikatorNirlabaReviewPage |
| Ekstraksi surat | Baca Surat Pernyataan bertanda tangan yang disusun di luar sistem | Untuk perbaikan yang suratnya sudah terlanjur dibuat di luar |
| Perapian UI | Rencana 2026-08-18 yang tertunda | Paling tidak mendesak |
7. Apa yang sebenarnya ada di Surat Pernyataan SABH
Saya sudah membaca surat aslinya dari DB produksi. Isinya tidak seperti dugaan
saya di revisi 2 dan 3.
7.1 Suratnya tidak memuat nilai koreksi sama sekali
Contoh nyata, Yayasan, koreksi Organ, 2705 karakter, 27 baris. Isinya identitas
notaris lalu enam klausa:
(1) Bahwa saya telah melakukan akses pendirian/perubahan pada Yayasan X pada tanggal 23 Juli 2026 dengan Nomor SP AHU-AH.01.03-...
(2) Bahwa saya telah melakukan akses Perbaikan Data Badan Hukum pada tanggal ..., dimana permohonan tersebut telah terbit surat SP ...
(3) Bahwa saya telah melakukan kesalahan pengisian data pada transaksi sebagaimana disebut dalam point pertama. ... Adapun jenis perbaikan data yang saya mohonkan meliputi Organ.
(4) Bahwa Badan Hukum ... telah memberikan kuasa kepada saya ...
(5) Bahwa saat ini ... tidak dalam sengketa hukum apapun.
(6) Bahwa saya telah membaca dan memahami Permenkumham No. 17 Tahun 2017 ...
Tidak ada "KOREKSI NPWP, lama ..., baru ...". Surat itu pernyataan tanggung
jawab notaris, bukan daftar koreksi. Satu-satunya jejak koreksi adalah nama
kategorinya di klausa (3), yaitu placeholder JENIS_PERBAIKAN.
Sama untuk Perseroan. Tiga sampel PT 2026, termasuk yang mengoreksi Pemegang Saham
dan Direksi sekaligus, semuanya 27 baris, sekitar 2.800 karakter, dan tidak satu
pun memuat kata "KOREKSI".
7.2 Akibatnya untuk prompt PT kita
Prompt surat_pernyataan_perbaikan.txt mengurai bagian "KOREKSI <BIDANG>"
dengan nilai lama dan baru. Bagian seperti itu tidak ada di artefak SABH.
Artinya prompt itu membaca Surat Keterangan buatan kita sendiri, bukan Surat
Pernyataan SABH.
Kesimpulan revisi 3 tetap berlaku (prompt PT sebagian besar bisa dipindah ke
Yayasan), tetapi alasannya keliru. Bukan karena templat SABH dipakai bersama,
melainkan karena dokumen itu milik kita dan kita yang menentukan bentuknya.
Fakta "templat 131/106 dipilih berdasarkan URL" benar, tapi tidak relevan.
Sisi baiknya: Surat Keterangan kita memang lebih berguna daripada artefak SABH,
karena membawa nilai lama dan baru secara eksplisit. Itu memperkuat pilihan
"Terbitkan" di §5, bukan melemahkannya.
7.3 Lalu nilai barunya dari mana
Bukan dari surat. Dari verifikator, dan tersimpan di tabel tersendiri:
tbl_transaksi_perbaikan_verifikasi_<tahun>
uid, id_badan_hukum, nomor_tiket, nama_badan_hukum, base,
nomor_transaksi, tahun, last_transaksi,
old_value, new_value, ← nilai lama dan baru ada DI SINI
editor, verifikator, status, catatan, created_date, approval_date, periksa
6.267 baris di 2026. Kolom editor dan verifikator yang terpisah juga
menegaskan verifikasi dua tingkat.
7.4 Pemakaian nyata membalik urutan kerja
Dari 2.114 permohonan perbaikan Yayasan sepanjang 2025 dan 2026:
| Kategori | Jumlah | Porsi | Kerja di prompt |
|---|---|---|---|
| Organ | 1.416 | 67,0% | roster, tersulit |
| Pendiri | 477 | 22,6% | roster, tersulit |
| NPWP | 214 | 10,1% | sederhana |
| Tempat Kedudukan dan Alamat | 168 | 7,9% | sederhana |
| Nomor Akta | 130 | 6,1% | sederhana |
| Kegiatan | 93 | 4,4% | menengah |
| Tanggal Akta | 68 | 3,2% | sederhana |
Ini membalik perkiraan saya di revisi 3. Di sana saya menulis empat kategori
sederhana "benar-benar gratis" dan tiga sisanya "jangan berharap sekali jadi".
Ternyata yang gratis itu hanya menutup sekitar seperempat pemakaian, sedangkan
Organ sendirian sudah dua pertiga.
Kerjakan Organ lebih dulu, lalu Pendiri. Mengerjakan empat yang sederhana
lebih dulu terasa produktif tapi hampir tidak menggerakkan apa pun.
Kabar baiknya, 82% permohonan hanya mengoreksi satu kategori (1.732 dari
2.114), jadi surat pada umumnya berisi satu bagian saja.
| Jumlah kategori | Permohonan |
|---|---|
| 1 | 1.732 |
| 2 | 341 |
| 3 | 27 |
| 4 sampai 7 | 14 |
7.5 Perkumpulan: 231 permohonan, dan dua kategori yang eksklusif
Revisi 4 hanya menanyakan Yayasan. Query yang sama untuk Perkumpulan (2025 + 2026,
231 permohonan, 95,2% hanya satu kategori). Angka yayasan di sini 2.115, satu
lebih dari 2.114 di §7.4, karena DB-nya hidup dan tumbuh di antara dua query:
| Kategori | n | % | Yayasan sebagai pembanding |
|---|---|---|---|
| Organ | 141 | 61,0% | 67,0% |
| NPWP | 48 | 20,8% | 10,1% |
| Nomor Akta | 19 | 8,2% | 6,1% |
| Tanggal Akta | 17 | 7,4% | 3,2% |
| Tempat Kedudukan dan Alamat | 12 | 5,2% | 7,9% |
| Kegiatan | 4 | 1,7% | 4,4% |
| Jenis Rapat | 1 | 0,4% | 0 |
| Pendiri | 0 | — | 477 (22,6%) |
Lima kategori dipakai bersama. Yang eksklusif hanya dua, dan keduanya mutlak:
Pendiri tidak pernah muncul untuk perkumpulan, Jenis Rapat tidak pernah untuk
yayasan. Itu yang mengunci keputusan tiga berkas terpisah di §9.3.
Koreksi terhadap dugaan sebelumnya: katalog perubahan memang tidak punya jenis
kegiatan untuk perkumpulan, tapi perbaikan mencatat 4 kasus nyata. Jadi Kegiatan
masuk ke kedua templat, bukan yayasan saja.
7.6 Urutan bagiannya bisa dipulihkan, tidak perlu dikarang
Array data_diperbaiki mempertahankan urutan checkbox formulir SABH, jadi urutan
kanonik bisa disimpulkan dari baris multi-kategori:
NPWP · Tempat Kedudukan dan Alamat · Nomor Akta · Tanggal Akta · Kegiatan ·
Pendiri · Organ · Jenis Rapat
Catatan kehati-hatian: Jenis Rapat tidak punya bukti urutan karena satu-satunya
barisnya berkategori tunggal, sehingga tidak menghasilkan pasangan apa pun dan
tersortir ke belakang secara default. Untuk kategori itu, katalog frontend yang
dibaca dari formulir SABH lebih tepercaya (§9.5).
8. Di mana dokumennya di SABH
Templat kosong, tabel Content:
| ID | Dokumen |
|---|---|
131 |
Surat Pernyataan (produksi) |
106 |
Surat Pernyataan (non-produksi) |
132 |
Surat Permohonan |
Placeholder: NAMA_BADAN_HUKUM, JENIS_BADAN_HUKUM, JENIS_PERBAIKAN, SK_SP,
NO_TRANSAKSI_SURAT, JENIS_SURAT, TGL_TERBIT_SURAT, TGL_SEKARANG,
TEMPAT_TGL_SEKARANG, KTP_NOTARIS, ALAMAT_KANTOR_NOTARIS.
Permohonannya, tabel tbl_transaksi_perbaikan_<tahun>:
| Kolom | Isi |
|---|---|
data_diperbaiki |
kategori yang dicentang, JSON array, contoh ["Organ"] |
isi_surat_pernyataan |
badan surat, pernyataan tanggung jawab, tanpa nilai koreksi (§7.1) |
path_surat_pernyataan |
PDF bertanda tangan |
path_npwp, path_surat_keterangan_domisili, path_lain_lain |
lampiran |
Nilai lama dan barunya, tabel tbl_transaksi_perbaikan_verifikasi_<tahun>,
kolom old_value dan new_value. Ini yang bisa dipakai sebagai kunci jawaban,
bukan isi_surat_pernyataan seperti yang saya klaim di revisi 2 dan 3.
Nilai jenis_badan_hukum sudah terverifikasi: perseroan, yayasan,
perkumpulan, huruf kecil semua.
Jumlah yang tersedia:
| Tahun | perseroan | yayasan | perkumpulan |
|---|---|---|---|
| 2026 | 93.298 | 944 | 125 |
| 2025 | 18.865 | 1.170 | 106 |
| 2024 | 2.119 | 495 | 115 |
Catatan sampingan: 346 permohonan perkumpulan di tiga tahun itu berarti untuk
alur perbaikan perkumpulan tidak sepenuhnya tanpa contoh, berbeda dengan
alur perubahan yang memang nol (lihat PR #19).
Koneksi memakai kredensial yang sudah ada di backend/.env. Plugin
'mysql_native_password' is not loaded yang muncul saat test suite ternyata
khusus lingkungan test; query langsung berjalan normal.
9. Templat penerbitan kita
9.1 Titik awal yang salah: templat PT ternyata rusak
Revisi 4 menulis bahwa templat PT memakai x_dasar_lama, x_ditempatkan_lama,
x_disetor_lama. Itu kunci yang dipancarkan generator, bukan yang diminta
templat. Keduanya sudah tidak sinkron sejak 25 Mei 2026 dan pecah total pada
551eed73 (10 Juli, penggantian font ke Arial).
Sebabnya struktural: berkas .docx itu artefak build dari
scripts/build-sk-template.ts, dan ada dua skrip yang bisa menghasilkannya.
adapt-user-template.ts memakai penamaan bergeser (v2) dan generator disesuaikan
ke sana; build-sk-template.ts memakai penamaan kanonik (v1) dan tidak pernah ikut
diperbarui. Menjalankan yang kedua menimpa yang pertama, diam-diam.
Yang kanonik adalah v1, dan tiga sumber sepakat:
| Sumber | Bukti |
|---|---|
docs/superpowers/specs/2026-05-19-surat-keterangan-perbaikan-pt-design.md §4.1 |
daftar editor: IX Modal, X Saham, XI Pemegang Saham, XII Direksi/Komisaris, XIII Email |
| spec yang sama | sahamTransfersBaru // for X, pemegangSahamBaru // for XI, direksiBaru/komisarisBaru // for XII |
frontend/src/lib/perbaikan-types.ts |
15 CorrectionFieldKey berurutan, mengerucut jadi 13 bagian dengan urutan identik |
_user-template-v2-source.docx bukan acuan: judul bagiannya sendiri kacau
(bagian Nilai Nominal Saham diberi label "XI" padahal placeholder-nya ix_, lalu
Pemegang Saham diberi label "XI" lagi) dan bagian KOREKSI SAHAM tidak ada sama
sekali. Itu draf kiriman, dan adaptasi Mei menularkan penomoran gesernya.
Akibat nyata pada surat yang terbit, diverifikasi dengan render sungguhan:
| Bagian | Gejala |
|---|---|
| IX Modal | hilang total, judulnya pun tidak muncul (ix_active dihardcode false) |
| X Saham | mencetak literal Akta Pemindahan: Nomor undefined Tanggal undefined, dan gerbangnya salah kunci (modalActive, bukan SAHAM) |
| XI Pemegang Saham | tabel kosong, judul ada isinya tidak |
| XII Direksi & Komisaris | dua daftar kosong (generator menggabung jadi satu roster yang templatnya tidak punya) |
| VIII KBLI, transfer saham | kebetulan cocok, satu-satunya yang utuh |
Tidak ada yang error. docxtemplater membiarkan tag tak dikenal kosong, dan satu-satunya
tes yang ada hanya memeriksa bahwa berkasnya tertulis. Drift itu terbit dua bulan.
9.2 Yang sudah dikerjakan
Generator diselaraskan ke kontrak kanonik (surat-keterangan-generator.ts):
modal x_* menjadi ix_*, ix_active tidak lagi dihardcode, x_active dipindah
ke active("SAHAM"), x_pemindahan_akta_* menjadi x_akta_*, xi_roster menjadi
xi_pemegang_saham dengan {nama, nik, npwp, jumlah_lembar}, xii_roster dipecah
menjadi xii_direksi + xii_komisaris, dan kunci hantu Nilai Nominal Saham dibuang.
adapt-user-template.ts dihapus. Sekarang hanya satu produsen templat.
Templat nirlaba dibangun, dan bukan hasil memangkas daftar PT. Daftar bagian,
urutan, dan labelnya dari data produksi SABH (§7.4). Tiga berkas terpisah, masing-masing
dengan varian blank:
PT 13 bagian
Yayasan I NPWP · II Tempat Kedudukan · III Nomor Akta · IV Tanggal Akta
V Kegiatan · VI Pendiri · VII Organ (Pembina, Pengurus, Pengawas)
Perkumpulan I NPWP · II Tempat Kedudukan · III Nomor Akta · IV Tanggal Akta
V Kegiatan · VI Organ (Rapat Anggota, Pengurus, Pengawas) · VII Jenis Rapat
Placeholder nirlaba dinamai menurut isi, bukan nomor romawi (organ_active,
pendiri_lama, bukan vi_active, vii_lama). Nomor romawi dihitung dari posisi dan
hanya dicetak di judul. Ini pelajaran langsung dari §9.1: prefiks ix_ versus x_
menyandikan posisi bagian ke dalam namanya, sehingga menyisipkan satu bagian
membuat setiap kunci sesudahnya menunjuk ke tempat lain tanpa suara.
Tes kontrak (sk-template-contract.test.ts, 19 tes) mengunci dua arah: setiap
{{tag}} di docx harus diproduksi generator, dan setiap kunci generator harus dibaca
templat. Plus render yang menolak sisa {{ dan kata "undefined". Diuji dengan
sengaja mengubah satu kunci: tiga tes gagal dan menyebut kedua sisi namanya.
Renderer diekstrak jadi renderSkTemplate supaya tes memakai konfigurasi
docxtemplater yang sama persis dengan produksi.
Verifikasi: tsc bersih, suite backend 4110 lulus 0 gagal.
9.3 Keputusan: tiga berkas, bukan satu
Usul revisi 4 ("satu templat bersama, bagian bersyarat lewat x_active")
dibatalkan. Alasan aslinya, SABH memakai satu templat untuk semua badan hukum,
benar tapi tidak mengikat kita: SABH tidak pernah menyerahkan formulir kosong
untuk diisi tangan, kita iya. Berkas blank diunduh notaris lalu diisi manual, jadi
bagian yang tidak bisa dijawab harus tidak ada di kertas, bukan disembunyikan lewat
penanda yang hanya bekerja saat dirender program.
Yang mengunci pemisahan Yayasan dari Perkumpulan bukan selera, tapi dua kategori
yang saling eksklusif: Pendiri 477 kali untuk yayasan dan nol untuk perkumpulan,
Jenis Rapat satu kali untuk perkumpulan dan nol untuk yayasan (§7.4). Ditambah
label organ yang berbeda, dan itu jatuh di bagian dengan volume 61-67%.
Pisahnya lewat satu konfigurasi (NIRLABA_VARIANTS), bukan tata letak kembar.
Menambah atau memindah bagian jadi satu baris data.
9.4 Status pemasangan: PT hidup, nirlaba belum
| Lapisan | Status |
|---|---|
| PT, penerbitan | Hidup. routes/surat-keterangan.ts (Terbitkan + Pratinjau) memakai templat yang sudah benar |
| PT, baca-ulang | Belum. perbaikan-processor.ts memuat prompt surat_pernyataan_perbaikan.txt, yang masih menjelaskan tabel 4 kolom versi v2 |
| Nirlaba, templat docx | Ada, 4 berkas |
Nirlaba, SK_TEMPLATE_PATHS.yayasan/.perkumpulan |
Hanya dirujuk tes kontrak |
| Nirlaba, endpoint penerbitan | Tidak ada. routes/nirlaba-perbaikan.ts cuma lookup + unggah dokumen |
| Nirlaba, halaman frontend | Sudah dirutekan, tombol Terbitkan disabled ("Pembuatan surat (PDF) menyusul"), draft di localStorage |
| Nirlaba, OCR akta perbaikan | Sudah jalan, AKTA_PERBAIKAN_YAYASAN/_PERKUMPULAN dirutekan ke extractNirlabaAkta |
Jadi yang tersambung di OCR adalah jalur aktanya, bukan jalur suratnya.
Menghidupkan templat nirlaba butuh buildValueMap versi nirlaba plus endpoint
terbitkan, yaitu persis §5 langkah 2.
9.5 Katalog yang sudah ada, dan tiga selisih yang sudah dirapikan
frontend/src/lib/nirlaba-perbaikan-fields.ts sudah memuat katalog kategori
nirlaba, ditranskrip dari FormPerbaikanData SABH. Katalog itu mengonfirmasi temuan
DB secara independen (yayasan punya Pendiri, perkumpulan punya Jenis Rapat sebagai
gantinya). Sempat berselisih di tiga tempat; ketiganya kini sudah diselaraskan:
| Selisih | Putusan | Alasan |
|---|---|---|
Urutan perkumpulan: katalog menaruh jenis_rapat sebelum organ, templat sebaliknya |
Katalog menang, templat ditukar | Inferensi urutan dari data_diperbaiki tidak bisa menempatkan Jenis Rapat: satu-satunya barisnya berkategori tunggal sehingga tidak menghasilkan pasangan urutan (§7.6). Katalog membacanya dari formulir SABH aslinya |
Nama kunci: katalog tempat_kedudukan_alamat, templat kedudukan_* |
Katalog menang, templat mengikuti | Katalog lebih dulu ada, dan halaman generator sudah menyimpan draft dengan kunci itu di localStorage. Mengubah templat tidak menyentuh draft siapa pun |
| Label organ: katalog memakai satu label untuk kedua base | Templat menang, katalog jadi per base | SABH sendiri membedakannya: "Organ (Pembina, Pengurus, Pengawas)" untuk yayasan versus "Nama Rapat Anggota, Pengurus, dan Pengawas" untuk perkumpulan. Perkumpulan tidak punya Pembina |
Dan sekarang dikunci tesnya. sk-template-contract.test.ts bertambah satu
pemeriksaan: urutan bagian yang dibaca balik dari docx yang sudah dibangun harus
sama persis dengan urutan kunci di katalog, per base. Diuji dengan sengaja mengurutkan
ulang katalog: tesnya gagal. Jadi ketiga selisih di atas tidak bisa kambuh diam-diam,
yang persis merupakan pelajaran §9.1 dipakai ke arah lain.
Pelajaran prosesnya tetap berlaku: katalog itu seharusnya dicari sebelum templat
disusun, bukan sesudah.
10. Keputusan yang saya perlukan
| # | Pertanyaan | Usul saya |
|---|---|---|
| 1 | Kerjakan irisan dua langkah di §5 lebih dulu? | Ya. Itu yang membuat alurnya hidup |
| 2 | Jalur utamanya "Terbitkan" (ketik data) atau unggah surat? | Terbitkan sebagai jalur utama, sesuai PT dan sesuai tujuan proyek. Unggah menyusul |
| 3 | Perbaikan lewat verifikator dua tingkat? | Ya, tapi setelah §5. Perlu diketahui: perbaikan berhenti selesai seketika |
| 4 | ~~Satu templat bersama PT + Yayasan, atau dua berkas?~~ | Terjawab, dan usul lama dibatalkan: tiga berkas terpisah (PT, Yayasan, Perkumpulan) dari satu konfigurasi. Alasannya di §9.3 |
| 5 | Wajibkan Surat Permohonan (step 2 SABH)? | Belum. Tambahkan kalau AHU meminta |
| 6 | AKTA_PERBAIKAN_YAYASAN dihapus dari enum? |
Jangan. Butuh migrasi, tanpa untung. Cukup hentikan pemakaiannya |
| 7 | Yayasan saja atau sekalian Perkumpulan? | Tulis untuk keduanya, uji Yayasan. Kini berdasar data: perkumpulan 231 permohonan versus yayasan 2.115, jadi bukan nol tapi memang 9:1 (§7.5) |
| 8 | ~~Boleh query DB SABH?~~ | Sudah dijalankan (read-only). Hasilnya di §7 dan §8 |
| 9 | Kerjakan Organ lebih dulu, bukan kategori sederhana? | Ya. Organ 67%, Pendiri 22,6%, sisanya seperempat pemakaian. Berlaku juga untuk perkumpulan (Organ 61%) |
| 10 | ~~Rapikan tiga selisih dengan katalog frontend sebelum generator nirlaba ditulis?~~ | Sudah dikerjakan dan dikunci tes (§9.5) |
| 11 | Selaraskan prompt surat_pernyataan_perbaikan.txt ke tata letak templat yang baru? |
Perlu, tapi itu wilayah prompt engine. Sisi penerbitan sudah benar, sisi baca-ulang belum (§9.4) |
11. Riwayat revisi
Revisi 5 (setelah templat dikerjakan dan DB SABH ditanya untuk perkumpulan):
| Sebelumnya | Sebenarnya |
|---|---|
Templat PT memakai x_dasar_lama, x_ditempatkan_lama, x_disetor_lama |
Salah. Itu kunci yang dipancarkan generator. Templat meminta ix_dasar_lama. Keduanya tidak sinkron sejak 25 Mei dan pecah 10 Juli; empat bagian terbit kosong dan satu mencetak kata "undefined" (§9.1) |
"Satu templat bersama, bagian bersyarat lewat x_active" |
Dibatalkan. Tiga berkas terpisah. Alasan lama (SABH satu templat untuk semua) tidak mengikat: SABH tidak menyerahkan formulir kosong untuk diisi tangan, kita iya (§9.3) |
| Kegiatan diduga khas yayasan | Salah. Katalog perubahan memang tidak punya kegiatan untuk perkumpulan, tapi perbaikan mencatat 4 kasus nyata (§7.5) |
| Daftar bagian nirlaba dari memangkas daftar PT | Dari data produksi: 2.115 permohonan yayasan + 231 perkumpulan, dengan urutan dipulihkan dari data_diperbaiki (§7.5, §7.6) |
| Katalog kategori nirlaba belum ada | Sudah ada di frontend/src/lib/nirlaba-perbaikan-fields.ts, dan berselisih di tiga tempat yang belum dirapikan (§9.5) |
.docx diperlakukan sebagai berkas yang bisa diedit |
Artefak build. Mengedit .docx akan ditimpa run skrip berikutnya (§9.1) |
Revisi 4 (setelah query langsung ke DB SABH):
| Sebelumnya | Sebenarnya |
|---|---|
| "Nilai baru ada di dalam teks Surat Pernyataan" | Salah. Surat itu pernyataan tanggung jawab notaris, tanpa satu pun nilai koreksi, untuk PT maupun Yayasan |
| Prompt PT bisa dipindah karena templat SABH dipakai bersama | Kesimpulannya benar, alasannya keliru. Prompt itu membaca Surat Keterangan buatan kita, bukan artefak SABH |
Kunci jawaban dari isi_surat_pernyataan |
Dari tbl_transaksi_perbaikan_verifikasi_*, kolom old_value / new_value |
| Empat kategori sederhana "benar-benar gratis" | Hanya menutup seperempat pemakaian. Organ sendirian 67%, Pendiri 22,6%. Urutan kerja dibalik |
| Verifikator dua tingkat (dari pembacaan kode) | Dikuatkan data: kolom editor dan verifikator terpisah |
Revisi 3 (setelah pertanyaan "bukankah hanya beda nama?"):
| Sebelumnya | Sebenarnya |
|---|---|
| Langkah 1 = "ganti dokumen yang dicari gerbangnya" | Terlalu ringan. Yang berpindah bentuk datanya, dari keadaan entitas utuh menjadi daftar koreksi per kategori |
| Tidak diuji apakah cukup ganti nama | Diuji di §3. Tidak cukup, dan hasilnya lebih berbahaya daripada buntu: PASS sambil melaporkan empat perubahan palsu |
| Tidak disebut apa yang bertahan | §3.4: rule entitas, lookup SABH, rangka route, 5 halaman, katalog kategori semuanya tetap terpakai |
Revisi 2 (setelah penelusuran asal-usul dan sumber SABH):
| Sebelumnya | Sebenarnya |
|---|---|
| "Menyimpang dari SABH, perlu diselaraskan" | Buntu total. Tidak ada permohonan yang bisa dikirim |
| Verifikator satu tahap | Dua tingkat, staff lalu kasi |
| Ekstraksi terhalang, belum ada contoh | Tidak terhalang. Teks surat dan kategorinya sudah ada di DB SABH |
| Fase 1 besar dengan migrasi | Dua langkah saja untuk bisa dipakai |
| Tidak menyebut jalur tanpa unggahan | PT sudah punya, dan itu model yang seharusnya ditiru |
| Templat surat belum dibahas | Templat SABH dipakai bersama PT |
12. Risiko
- Langkah 1 mengubah flow yang sudah berdiri. Murah sekarang karena review
projector masihnullsehingga belum ada yang bergantung padanya. Mahal setelah
projector diisi. - Perkumpulan ikut berubah, karena semua kode dipakai bersama. Memang sesuai,
tapi tetap tanpa satu pun contoh dokumen. Jangan diklaim jalan. - Verifikator jadi wajib membuat perbaikan tidak lagi selesai seketika. Itu
perilaku SABH yang benar, tapi mengubah kesan saat demo. - Tabel roster tetap bagian tersulit pada ekstraksi, sama seperti pada PT.
- Prompt baca-ulang masih tertinggal. Sisi penerbitan PT sudah benar, tapi
surat_pernyataan_perbaikan.txtmasih menjelaskan tata letak v2. Selama itu belum
diselaraskan, surat terbitan kita sendiri diurai dengan panduan yang salah. - Templat nirlaba belum tersambung ke apa pun selain tes kontrak. Jangan diklaim
jalan hanya karena berkasnya sudah ada (§9.4).