Persona Split Wave — Done Report (2026-07-11)
Scope (Efran, 5 items): ① split verifikator PT vs Apostille/Legalisasi · ② notaris dashboard = notaris transactions only · ③ admin role + admin UI · ④ debug menus out of the notaris view · ⑤ friendlier notaris dashboard.
Status: ALL DONE & DEPLOYED — staging ahu-ai-ocr:8462be94 live on x056.ahu-demo.ocr.val.id (192.168.83.20:3520). Both suites green (backend 2521 pass / 0 fail, frontend 970 pass / 0 fail); migrations auto-applied; every persona verified live with headless screenshots + API checks.
The new persona model
| Role | Home | Sees |
|---|---|---|
notaris |
/dashboard (new friendly home) |
PT family only (?family=notaris) |
verifikator_pt |
/verifikator |
PT queue only (?domain=pt) |
verifikator_apostille |
/verifikator |
Apostille queue only (?domain=apostille) |
perseroan |
/pp/pendirian/klasifikasi |
PP flows (unchanged) |
umum |
/apostille |
Their apostille filings (unchanged) |
admin |
/admin |
Everything + configuration + relocated debug tools |
The localStorage role key is versioned to userRole.v2 — a stale pre-split "verifikator" value can't satisfy any guard, so old browsers simply restart at the notaris default instead of bouncing in redirect loops.
① Verifikator split (W1)
- Frontend:
UserRolegainsverifikator_pt/verifikator_apostille; role switcher,ROLE_HOME, RoleGuard blocks, and sidebar navs are per-team. The queue page (VerifikatorDashboardPage) scopes itself from the persona: per-team title/copy, the PT team loses the APOSTILLE flow option, the apostille team loses the PT-specific jenis (PAD/PPAD) and flow filters entirely. The sidebar pending badge counts that team's backlog only. - Backend:
GET /api/verifikator/submissionstakesdomain=pt|apostille(pt = every non-APOSTILLE flow — future notaris domains like yayasan/perkumpulan land on that side).Roletype, the VERIFIKATOR route policy, andrequireVerifikatorRole(c, action, domain)know both teams; apostille decide/spesimen-upload require the apostille domain, perbaikan decide/advisory the PT domain. The legacy bare"verifikator"role stays accepted so already-issued tokens keep working. - Route guards: apostille review/list =
umum + verifikator_apostille + admin; the 5 PT verifikator review pages =verifikator_pt + admin; the shared/verifikatorqueue = both teams + admin. - Dev login (
/login) now mints all four roles and syncs the persona.
② Notaris scope (W2)
GET /api/submissions?family=notaris filters to the 10 PT-family types (pendirian, perubahan, perbaikan, akuisisi, penggabungan, peleburan, pembubaran, berakhirnya, laporan RUPS, peralihan PP→PT). Yayasan and perkumpulan will simply join NOTARIS_FAMILY_TYPES when those flows land. The notaris dashboard reads this scope — PP and Apostille rows are gone from the notaris view (verified live: scoped call returns PT types only, unscoped returns PP too).
③ Admin role + UI (W3)
/admin— Semua Transaksi: the former dense DashboardPage, promoted: family filter tabs (Semua/PT/PP/Apostille), labels for all 15 flow types, per-family row actions (PT rows keep the step indicator +destinationForrouting; PP/Apostille rows link to their canonical pages via the new sharedlib/submission-actions.ts). Stat cards + document work-queue + perbaikan list stay here./admin/settings— Konfigurasi Sistem: newAppSettingKV table (migration20260711080000_app_setting); DB override wins over env default, "Kembalikan" deletes the override. Current knobs: fast-track daily quota, window open/close hour (WIB) — read by the fast-track gates throughservices/app-settings.ts(15 s in-process cache, invalidated on write), so quota/window changes apply without a redeploy. Plus read-only system posture: SECURITY_ENFORCE mode, OCR provider, signature-verify AI (Terhubung), specimen MinIO (belum — manual-upload fallback).- API:
/api/adminmounted with an admin-only route policy + in-handlerrequireAdminRoleguard on the PUT (same shadow/enforce semantics as everything else). Live round-trip verified: PUT quota 5 →source: db→ PUT null → back tosource: env. - Admin passes every RoleGuard block, so the all-transactions table can deep-link into any family's working/review pages.
④ Debug menus out of the notaris view (W4)
Notaris sidebar is now just Dashboard · Permohonan Baru · Perbaikan Data PT · Proses Dokumen. Analitik, Uji Klasifikasi, and Pengaturan (now "Data & Penyimpanan") moved into the admin nav, and their routes are admin-guarded — a notaris deep-linking /settings gets bounced home. (Pengaturan also left the umum/perseroan/verifikator navs; configuration is the admin's job.)
⑤ Friendly notaris home (W5)
New NotarisDashboardPage: greeting + date, three big CTAs (Permohonan PT Baru / Perbaikan Data PT / Proses Dokumen), a "Perlu Tindakan Anda" strip (rows waiting on the notaris: siap ditinjau, kendala, perlu perbaikan, pilih perusahaan — capped at 6 with an overflow note), and "Permohonan Saya" with human status chips (Siap Ditinjau / Menunggu Verifikasi / Perlu Perbaikan / Selesai / Kendala) + the familiar mini step indicator. No OCR-accuracy numbers, no work queues, no staff metrics.
Verification
- Suites: backend 2521 pass (incl. new
w-admin-and-scoping.test.ts: domain scoping ×3, family scoping ×2, admin-settings round-trip ×3), frontend 970 pass (LoginPage + sidebar tests updated to the split roles/versioned key). Architecture fitness gates green. - Live (staging :3520):
AppSettingtable present;?domain=pt→ 0 rows /?domain=apostille→ the 1 demo apostille row;?family=notaris→ PT types only; admin-settings PUT/revert round-trip; headless screenshots of all four affected personas (notaris home, admin overview, admin config, both verifikator queues) all render correctly with their scoped navs.
Deliberately noted
- Roles are still a UX separator, not security — RoleGuard is localStorage-based by design (PoC, no auth). The backend guards are real but run in shadow mode until
SECURITY_ENFORCE=on; the JWT role model is already split-aware for that day. - The pre-split
"verifikator"JWT role remains accepted everywhere both teams are; drop it whenever old tokens no longer matter. - Admin currently reuses the generic 20-row submissions list; if the admin table needs pagination/search over full history, that's a follow-up endpoint.