# Setrip — Admin Roadmap (Index) · ✅ ALL DELIVERED

Status implementasi kemampuan admin agar admin **dapat mengontrol seluruh aplikasi saat ada insiden**, bukan hanya read-only dashboard.

> **Prinsip:** admin adalah safety net terakhir saat sistem otomatis gagal atau ada bad actor. Setiap action admin harus auditable (siapa, kapan, alasan), idempotent, dan terbatas hanya untuk admin yang terdaftar di `ADMIN_EMAILS`.

> **Status:** 6 dari 6 roadmap area selesai (4 fully, 2 dengan minor skip yang dijelaskan di archive masing-masing). Detail lengkap per area di [docs/archive/](docs/archive/).

---

## Baseline — yang BISA admin lakukan sekarang

| Area | Fungsi | File |
|---|---|---|
| **Dashboard** | View count: verifikasi PENDING, refund per status, payout per status | [app/admin/page.tsx](app/admin/page.tsx) |
| **Global search** | Search bar di sidebar — by email, order_id, cuid, fuzzy trip/user | [features/admin/components/admin-search-bar.tsx](features/admin/components/admin-search-bar.tsx) |
| **Trips** | List + search + detail; force-cancel dengan auto-refund (admin intervention) | [app/admin/trips/](app/admin/trips/) |
| **Users** | List + search + filter; detail dengan trip + booking history; suspend/unsuspend; manual verify (override KYC); analytics | [app/admin/users/](app/admin/users/) |
| **Bookings detail** | Timeline lintas Payment + Refund + Payout, raw callback viewer, Midtrans reconcile | [app/admin/bookings/[id]/page.tsx](app/admin/bookings/[id]/page.tsx) |
| **Verifikasi KYC** | Approve / Reject / Reopen REJECTED / Request re-upload (lebih lembut dari reject) / Manual override; filter date range + reviewer; CSV export | [app/admin/verifications/page.tsx](app/admin/verifications/page.tsx) |
| **Refund** | Create manual, approve, reject, mark SUCCEEDED/FAILED; filter date/reviewer/reason; link ke booking timeline; CSV export | [app/admin/refunds/page.tsx](app/admin/refunds/page.tsx) |
| **Payout** | View per status, mark PAID; filter date/processor; link ke booking timeline; CSV export | [app/admin/payouts/page.tsx](app/admin/payouts/page.tsx) |
| **Audit Log** | View semua action admin lintas entity; filter by admin/entity/action/date | [app/admin/audit-log/page.tsx](app/admin/audit-log/page.tsx) |
| **System Health** | Status cron jobs (last run, health badge), 20 recent runs, **stale state alerts** (Payment AWAITING > 25h, Payout HELD overdue, Refund stuck), **Discord webhook** untuk cron FAILED | [app/admin/system/page.tsx](app/admin/system/page.tsx) |

**Aksi mutating yang diblokir untuk suspended user:** sign-in (NextAuth), `createTripAction`, `joinTripAction`. Trip public list otomatis sembunyikan organizer suspended.

**Audit trail otomatis:** semua aksi admin (suspend, force-cancel, reconcile, approve/reject/reopen/request-reupload/manual-override verification, create/decide refund, mark payout PAID) tercatat di `AdminActionLog` via `auditLog.record()`.

Auth admin: env `ADMIN_EMAILS` → cek di [lib/admin.ts](lib/admin.ts), dipassing ke session via [lib/auth.ts](lib/auth.ts).

---

## Roadmap per area — status final

| Roadmap | Prioritas | Status | Archive |
|---|---|---|---|
| Trip Operations | 🔴 HIGH | ✅ Delivered | [ADMIN_TRIP_OPS_ROADMAP.md](docs/archive/ADMIN_TRIP_OPS_ROADMAP.md) |
| Payment Operations | 🔴 HIGH | ✅ Delivered | [ADMIN_PAYMENT_OPS_ROADMAP.md](docs/archive/ADMIN_PAYMENT_OPS_ROADMAP.md) |
| Audit & Investigation | 🔴 HIGH | ✅ Delivered | [ADMIN_AUDIT_ROADMAP.md](docs/archive/ADMIN_AUDIT_ROADMAP.md) |
| User Management | 🟡 MEDIUM | ✅ Delivered | [ADMIN_USER_MGMT_ROADMAP.md](docs/archive/ADMIN_USER_MGMT_ROADMAP.md) |
| Verification | 🟡 MEDIUM | ✅ Delivered | [ADMIN_VERIFICATION_ROADMAP.md](docs/archive/ADMIN_VERIFICATION_ROADMAP.md) |
| System Health | 🟡 MEDIUM | ✅ Delivered | [ADMIN_SYSTEM_HEALTH_ROADMAP.md](docs/archive/ADMIN_SYSTEM_HEALTH_ROADMAP.md) |

**Minor item yang sengaja di-skip** (dengan justifikasi di archive):
- Audit Phase 2.5 — page `/admin/search` full-results (dropdown 10 hit cukup).
- Verification Phase 3.1 — snapshot full data per submission (counter + array rejection cukup).
- System Health Phase 4.3 — push notif harian dari stale alerts (admin sudah lihat banner di `/admin/system`).
- Trip Ops Phase 3 — trip edit override (skip MVP, evaluate ulang saat ada keluhan konkret).

---

## Tindakan manual setelah deploy versi final

```bash
# Apply 5 migration baru (urutan time-stamp tidak masalah, prisma resolve):
#   - 20260518150000_add_trip_admin_cancel
#   - 20260518160000_add_user_suspension
#   - 20260518170000_add_cron_run
#   - 20260518180000_add_admin_action_log
#   - 20260518190000_verification_enhancements
npx prisma migrate deploy

# (Opsional) Set env Discord webhook untuk alert cron failed
echo 'ADMIN_ALERT_WEBHOOK_URL=https://discord.com/api/webhooks/...' >> .env

# Restart Next.js / PM2 supaya Prisma client + env baru ter-load
pm2 restart setrip --update-env
```

Brief admin tentang kapabilitas baru (lihat archive masing-masing untuk detail SOP):

- **Global search** di sidebar — ketik email, order_id, atau cuid; auto-detect ke detail page yang tepat.
- **Force-cancel trip** di `/admin/trips/[id]` — saat organizer unreachable / dispute.
- **Reconcile Midtrans** di `/admin/bookings/[id]` — saat peserta lapor "sudah bayar tapi status belum update".
- **Suspend user** di `/admin/users/[id]` — untuk scam/harassment.
- **Manual verify** di `/admin/users/[id]` — partner trusted, bypass KYC, ter-flag jelas.
- **Reopen verification** di REJECTED card — organizer kirim ulang foto via email/WA.
- **Request re-upload** di PENDING card — lebih lembut dari reject; organizer dapat banner di `/verify`.
- **System status** di `/admin/system` — cek setiap pagi, lihat alert stale + cron health.
- **Discord alert** otomatis saat cron FAILED (kalau `ADMIN_ALERT_WEBHOOK_URL` di-set).
- **Audit log** di `/admin/audit-log` — bukti compliance untuk audit eksternal.
- **CSV export** di refunds/payouts/verifications — laporan keuangan/compliance.
- **User stats** di `/admin/users/stats` — total user, signup per minggu.

---

## File-file penting yang ditambahkan / diubah

**Service & helper:**
- [server/services/audit-log.service.ts](server/services/audit-log.service.ts) — log polymorphic
- [server/services/system-health.service.ts](server/services/system-health.service.ts) — stale state detection
- [server/services/admin-search.service.ts](server/services/admin-search.service.ts) — search dispatcher
- [server/services/user.service.ts](server/services/user.service.ts) — suspend/unsuspend
- [lib/cron-runner.ts](lib/cron-runner.ts) — `runCron()` wrapper
- [lib/admin-notify.ts](lib/admin-notify.ts) — Discord webhook helper
- [lib/auth-guards.ts](lib/auth-guards.ts) — `requireActiveUser()`
- [lib/csv.ts](lib/csv.ts) — CSV builder

**Model baru:** `AdminActionLog`, `CronRun` + 5 migration baru di `prisma/migrations/`.

**Admin UI baru:** `/admin/trips`, `/admin/users`, `/admin/bookings/[id]`, `/admin/system`, `/admin/audit-log`, `/admin/users/stats`.

**API routes baru:** `/api/admin/search`, `/api/admin/export/{refunds,payouts,verifications}`.
