think
16px
820px

Task 7 Report — Pembubaran PT routing + gating (THE LAUNCH SWITCH)

Status: COMPLETE — commit 458de24 feat(pembubaran): LAUNCH SWITCH — BUILT flip + Berakhirnya doc-set predicate + ladder rung below akuisisi on feat/pt-flows-registry.

What was done (TDD: RED → GREEN)

  1. RED first: created backend/src/routes/__tests__/pembubaran-routing.test.ts verbatim from the brief (7 tests); confirmed failing (BERAKHIRNYA_PACKAGE not exported).
  2. backend/src/services/akta-txn-classifier.ts
    - BUILT_AKTA_TXN_TYPES += "pembubaran" (LAUNCH SWITCH — third v2-generic tenant).
    - SYSTEM_PROMPT: replaced the two overlapping one-liners with the spec §4.2 appoints-vs-accepts cue (pembubaran = deed DISSOLVES + APPOINTS likuidator, liquidation BEGINS; berakhirnya = deed ACCEPTS pertanggungjawaban, liquidation ENDS).
  3. backend/src/routes/submissions.ts
    - Exported BERAKHIRNYA_PACKAGE(files: InferableFile[]): boolean directly above detectUnsupportedAktaType, exactly per the brief (AKTA_BERAKHIRNYA / LAPORAN_LIKUIDASI / SURAT_PERMOHONAN / BUKTI_PENGUMUMAN_152 clauses + the ≥2-carrier count via mapToDocumentType, never the raw label; full §6.2 doc-comment incl. the C5 "quoted identically" note; the brief's NOTE honored — no BUKTI_PENGUMUMAN_152 map line added).
    - detectUnsupportedAktaType: predicate check FIRST → returns "berakhirnya" before the per-file unbuilt scan.
    - inferSubmissionType: return union += "PEMBUBARAN_PT"; precedence doc-comment updated (… > Akuisisi > Pembubaran > Perubahan > …); rung inserted BETWEEN AKTA_AKUISISI and AKTA_PERUBAHAN with the belt-and-braces && !BERAKHIRNYA_PACKAGE(files) guard (BELOW akuisisi — opposite of peleburan's placement; brief's comment kept).
    - mapToDocumentType("SURAT_LIKUIDATOR") → "SURAT_LIKUIDATOR" (next to the BUKTI_PENGUMUMAN line, above the AKTA fallback); getProcessingOrder("SURAT_LIKUIDATOR") → 4 (next to domisili).
  4. backend/src/routes/klasifikasi.ts
    - PEMBUBARAN_DOC_TYPES (11 entries verbatim from the brief) after PELEBURAN_DOC_TYPES; added to the LABEL_MAP spread; ?type=pembubaran branch in the labels endpoint + route-comment type list extended.
  5. Stale fixture flips (canonical unbuilt example moves pembubaran → berakhirnya; launched-state assertions only, nothing weakened):
    - laporan-rups-routing.test.ts:14AKTA_BERAKHIRNYA/berakhirnya; describe-title ladder text now includes Pembubaran between Akuisisi and Perubahan.
    - klasifikasi-akta-txn.test.ts → unbuilt example flips to AKTA_BERAKHIRNYA (comment updated per brief); built-types test GAINS AKTA_PEMBUBARAN → null; override test now AKTA_BERAKHIRNYA → AKTA_PERUBAHAN. The refine test's AKTA_PEMBUBARAN label expectations unchanged.
    - peleburan-routing.test.ts:12 (risk-flagged; not in the brief's file list) → dark-type fixture flips to AKTA_BERAKHIRNYA.
    - akta-txn-classifier.test.ts (found in self-scan; not in the brief's file list): BUILT-set enumeration gains "pembubaran"; the two supported:false pembubaran assertions flip to true ("recognized-and-supported (its flow shipped)") — same launched-state pattern the file already applied to peleburan/laporan_rups.

Verification

  • New suite: pembubaran-routing.test.ts — 7/7 pass (RED first, then GREEN).
  • Brief's GREEN set (pembubaran + klasifikasi-akta-txn + laporan-rups + peleburan + akuisisi): 42 pass / 0 fail.
  • Broad regression (those + akta-txn-classifier + supporting-doc-classifier + submission-dispatch + flow-engine dispatch-routing / pembubaran-flow / -schema / -context / registry / rules-pembubaran + akta-pembubaran-deed-passes + pembubaran-rups-fallback + resume-pembubaran-recovery): 103 pass / 0 fail, 415 expects, 17 files.
  • Typecheck: bunx tsc --noEmit clean.
  • Tests ran against the isolated ahu_ocr_test DB (bunfig preload confirmed).

Self-review traces (predicate both-sides + ladder position)

  1. Co-upload pembubaran + akuisisi → AKUISISI_PT: the AKTA_AKUISISI rung is checked before the new pembubaran rung; asserted inferSubmissionType([AKTA_PEMBUBARAN, AKTA_AKUISISI]) === "AKUISISI_PT" (and + AKTA_PELEBURAN → PELEBURAN_PT). Rung sits BELOW akuisisi.
  2. Bare pembubaran → PEMBUBARAN_PT: detectUnsupportedAktaType([AKTA_PEMBUBARAN]) === null (BUILT) and inferSubmissionType([AKTA_PEMBUBARAN, KTP]) === "PEMBUBARAN_PT", incl. the userOverride confident-wrong re-map.
  3. 6-doc Berakhirnya package → NOT pembubaran, both sides: gate side — detectUnsupportedAktaType([AKTA_PEMBUBARAN, 2× BUKTI_PENGUMUMAN]) === "berakhirnya" and the live create route returns {supported:false, detectedType:"berakhirnya"} with no Submission row; rung side — the !BERAKHIRNYA_PACKAGE(files) guard means even a direct inferSubmissionType call can't steal the package. A single Ps.147 clipping does NOT trip it ([AKTA_PEMBUBARAN, BUKTI_PENGUMUMAN] → PEMBUBARAN_PT).

Deviations from the brief

  • Two extra test files flipped and committed beyond the brief's git add list (peleburan-routing.test.ts, akta-txn-classifier.test.ts) — both used pembubaran as the dark-type/unsupported fixture and would have broken at this commit; flips are launched-state-only, matching the plan's risk flags. No production-code deviation.
  • This file previously held the Peleburan cycle's task-7 report (commit e8e81aa); overwritten per the task directive (the Peleburan report remains in git history).

Concerns

  • None blocking. BUKTI_PENGUMUMAN_152 currently falls to the "AKTA" fallback in mapToDocumentType — intentional per the brief's NOTE (the explicit predicate clause covers it until the Berakhirnya flow maps the _149/_152 fine labels).
  • The predicate's LAPORAN_LIKUIDASI / SURAT_PERMOHONAN clauses are dormant until those labels exist upstream — written now so Berakhirnya only appends names (C5).