admin-mvp-1-ia-handover.html · Stack: React 19 + TanStack Start (SPA) · shadcn amber b1MJ9vRwY6 · light-mode iter-1
Settings-tier · Audit Log (A1 epic, insert-only 7thn) + Cron Jobs admin (partner-discussion Item 2) · light mode · Indonesian · WIB
| Timestamp (WIB) | Aktor | Aksi | Entitas | ID | IP |
|---|---|---|---|---|---|
| 31 Mei 14:32:08 | FAFahrul A. | pricing.update | pricing_matrix | #PM-2041 | 103.xx.12.4 |
| 31 Mei 14:02:11 | FAFahrul A. | schedule.approve | schedule | #1042 | 103.xx.12.4 |
| 31 Mei 11:18:45 | DKDewi K. (OPS) | schedule.cancel | schedule | #1037 | 103.xx.55.2 |
| 31 Mei 10:05:30 | RnRina (FIN) | settlement.mark_paid | settlement | #bulk-22 | 103.xx.77.9 |
| 30 Mei 16:48:02 | FAFahrul A. | tutor.suspend | tutor | #T-088 | 103.xx.12.4 |
| 30 Mei 09:30:15 | RnRina (FIN) | period.close | period | #2026-04 | 103.xx.77.9 |
| Kolom | Sebelum | Sesudah |
|---|---|---|
| amount (HSK3·SMA10·REG) | Rp 250.000 | Rp 270.000 |
| effective_from | — | 2026-06-01 |
DB constraint: no UPDATE, no DELETE. Retensi 7 thn (legal). Setiap entry permanen — dispute-proof. Cover 6 financial touch-point (create/approve/cancel/finalize/reconcile bill/reconcile payout) + master-data edit + FM events.
Klik row → expand diff (field, sebelum, sesudah) + alasan + IP. Buat dispute ("kok harga siswa ini beda?") + forensik.
Date range · aktor (Combobox) · entity_type (Select) · entity_id (search) · aksi. Server-side query + pagination (volume tinggi, 50-100k/thn).
ADMIN = full. OPS = own actions + scoped entity. FINANCE = finance actions. Per permission (Negation ACL).
entity_id clickable → buka entity detail (sesi #1042 → schedule detail). Cross-ref dari audit ke entity + balik (tab Riwayat per entity).
DataTable (TanStack, server-side), DateRangePicker, Combobox (actor), Select, Sheet/inline-expand (diff), Badge (action type). Ekspor → Excel/CSV.
| Tugas | Jadwal | Terakhir dijalankan | Status | Jadwal berikutnya | |
|---|---|---|---|---|---|
| Tutup periode bulanan pemicu period.close | 0 0 1 * *tiap tgl 1, 00:00 | 1 Mei 00:00 | Berhasil | 1 Jun 00:00 | |
| Pembersihan strike kedaluwarsa hapus strike >90 hari | 0 0 * * *harian 00:00 | 31 Mei 00:00 | Berhasil · 4 dibersihkan | 1 Jun 00:00 | |
| Tutup jendela banding FM tutup PENDING_L2 >14 hari | 0 0 * * *harian 00:00 | 31 Mei 00:00 | Berhasil · 0 ditutup | 1 Jun 00:00 | |
| Hitung ulang aging hitung ulang bucket outstanding | 0 1 * * *harian 01:00 | 31 Mei 01:00 | Berhasil | 1 Jun 01:00 | |
| Kirim ulang email selamat datang kirim ulang antrian gagal | */30 * * * *tiap 30 menit | 31 Mei 02:00 | 1 gagal kirim ulang | 31 Mei 02:30 |
List job + schedule + last/next run + status. Manual trigger (debug / re-run / period-close override). Drill → run history + log. NO edit cron expr / add-remove job (code-side, partner authority).
Period close (monthly) · Strike decay (daily) · FM banding-close (daily) · Aging recalc (daily) · Notif retry (30 min). Semua WIB.
Dot warna: hijau sukses / kuning warning (1 gagal retry) / merah error / abu idle. + result summary ("4 cleared").
ADMIN-only page. Kenapa UI (bukan CLI-only): ops helper future gak boleh ke-lock dari Wrangler. Incident response butuh manual trigger.
Semua cron run WIB (Asia/Jakarta). Period close = WIB midnight tgl 1. Log timestamp WIB. Per lock doc.
DataTable (job list), Badge/status dot, Button (trigger), inline-expand (run history + log), AlertDialog (confirm manual trigger period-close — high-impact).