think
16px
820px

Task 14 — Frontend review + status pages + routes (Peleburan PT)

Status: DONE. TDD RED → GREEN, tsc clean, committed.
Commit: 26ba87dfeat(peleburan): frontend review + verifikasi-aware status pages + routes
Branch: feat/pt-flows-registry

What shipped

  • frontend/src/pages/PeleburanReviewPage.tsx (new) — flat pendirian-shaped review:
  • Sections: Data Perseroan Baru, Akta Notaris, Modal & Saham, Pengurus & Identitas, Maksud & Tujuan (KBLI), plus the two peleburan sections PT Sumber Peleburan (read-only source snapshots with resolutionStatus + BLOKIR badges) and RUPS & Pengumuman Koran (per-source RUPS dates + editable nama/tanggal koran).
  • Per-section explicit Setujui Bagian / Batalkan PersetujuanPOST /sections/:key/approve|unapprove.
  • Per-field Konfirmasi on non-CONFIRMED/LOCKED akta fields → generic POST /submissions/:id/documents/:docId/fields/confirm.
  • Koran editor → PUT /peleburan/submissions/:id/koran ({ namaKoran, tanggalPengumuman }).
  • Hasil Validasi list with FAIL Override (prompt reason) → POST /submissions/:id/override-validation.
  • Submit gate = canSubmit (READY + no un-overridden FAIL + missingSections empty + unresolvedSourceOrdinals empty) pre-empts the CTA; dialog "Kirim ke Verifikator" → Kirim SekarangPOST /submit → navigate /status. No warning-ack step (verifier reviews downstream — akuisisi parity).
  • frontend/src/pages/PeleburanStatusPage.tsx (new) — verifikasi-aware; drives computeFlowStep(PELEBURAN_PT, COMPLETED, {status}) + useVerifikasiData; redirects non-COMPLETED and PERBAIKAN back to /review; uses base-ui render={<Link/>} (no asChild).
  • frontend/src/routes.tsx (modified) — imported the three Peleburan pages; added peleburan/:submissionId/{extraction,review,status} right after the laporan-rups rows (extraction/review after L86, status after the laporan-rups status row). URLs match T11 create-route + T12 destinations exactly.
  • frontend/src/pages/__tests__/PeleburanReviewPage.test.tsx (new) — 5 tests, verbatim from the brief.

Deviations from the brief's literal implementation code (required to make the brief's OWN tests pass + keep tsc clean)

  1. Sumber header count wrapped in a <span>getByText("PT Sumber Peleburan") is an exact match; the inline ({sources.length}) made the h2's direct text "PT Sumber Peleburan (2)". Wrapping the count in a child element keeps the h2's own text node exactly "PT Sumber Peleburan".
  2. Koran name rendered as visible text (a "Pengumuman terbaca: …" caption) — getByText(/Harian Kompas/) needs it as text; the brief only had it in an <Input defaultValue> (invisible to getByText).
  3. Unresolved message de-duplicated — the brief rendered "PT sumber belum teridentifikasi" in BOTH the sumber section <p> and the footer <span>, so getByText(/sumber belum teridentifikasi/i) would throw on multiple matches. Kept the footer span (the test's target); reworded the section paragraph to "Sebagian PT sumber belum dipilih …".
  4. Koran draft merge without duplicate object keys — replaced the brief's { …, ...d, key: e.target.value } duplicate-key pattern with { ...(d ?? koranBase), key: e.target.value } (clean single-field merge; also avoids TS2783).
  5. Status page uses render={<Link/>} not asChild — the project's base-ui Button has no asChild (LaporanRupsStatusPage precedent + memory note).

Tests

  • PeleburanReviewPage.test.tsx: 5/5 pass (RED confirmed first — module-not-found).
  • Regression — peleburan/akuisisi/laporan-rups/flow-steps suites: 13 files / 79 tests pass (incl. T12 peleburan-flow, T13 PeleburanSourcesPanel, AkuisisiDeltaReviewPage, LaporanRupsReviewPage).
  • Full frontend suite: 487 tests pass, 86/87 suites pass. The one failing suite is PerbaikanReviewPage.test.tsx (import-time ReferenceError: DOMMatrix is not defined from react-pdf/pdfjs under jsdom) — pre-existing and environmental: it fails identically with my routes change stashed and does not import any Task-14 file.

tsc

cd frontend && bunx tsc --noEmit → exit 0 (clean).

Concerns

  • Pre-existing PerbaikanReviewPage.test.tsx DOMMatrix failure is orthogonal to this task (react-pdf jsdom polyfill) — flagged, not fixed (out of scope).
  • Status page has no dedicated unit test (brief only specified the review-page test file); it is tsc-checked and wired.