3.6 KiB
3.6 KiB
Setrip — Admin User Management Roadmap (ARCHIVED — DELIVERED 2026-05-18)
Admin perlu bisa cari user dan suspend akun yang melakukan abuse (scam, harassment, fake review).
Skenario nyata: organizer scam berkali-kali bikin trip palsu pakai alias berbeda. Peserta lapor harassment dari user lain di grup WA trip.
Status delivery
| Phase | Status | Catatan |
|---|---|---|
| Phase 1 — User List & Detail | ✅ Delivered | Search by email/name, filter tab (ALL/ACTIVE/SUSPENDED), stats (trip dibuat, booking, total spent). |
| Phase 2 — User Suspension | ✅ Delivered | Schema baru User.suspended, auth gate sign-in + helper requireActiveUser di mutating actions, trip public list otomatis sembunyikan organizer suspended. |
| Phase 3 — User Analytics | ⏳ Deferred | Skip MVP — tidak ada use case konkret. |
Phase 1 — User List & Detail ✅
| # | Item | Status | File |
|---|---|---|---|
| 1.1 | userRepo.searchForAdmin({ q?, suspended? }) |
✅ | server/repositories/user.repo.ts |
| 1.2 | Page /admin/users — list + search + tab filter (ALL/ACTIVE/SUSPENDED) |
✅ | app/admin/users/page.tsx |
| 1.3 | Page /admin/users/[id] — detail dengan trip dibuat + booking history + profile + verification |
✅ | app/admin/users/[id]/page.tsx |
| 1.4 | Stats cards: trip dibuat, booking aktif, total spent (PAID) | ✅ | app/admin/users/[id]/page.tsx |
| 1.5 | Link "Users" di admin navbar | ✅ | components/admin/admin-sidebar.tsx |
Phase 2 — User Suspension ✅
| # | Item | Status | File |
|---|---|---|---|
| 2.1 | Migration: suspended Boolean, suspendedAt, suspendedReason, suspendedById (FK User SET NULL) |
✅ | prisma/migrations/20260518160000_add_user_suspension/ |
| 2.2 | userService.suspendUser + unsuspendUser (idempotent + cek tidak suspend diri sendiri + reason min 10 char) |
✅ | server/services/user.service.ts |
| 2.3 | Block sign-in di NextAuth signIn callback (email-based, jalan untuk Credentials + OAuth) |
✅ | lib/auth.ts |
| 2.4 | Helper requireActiveUser(userId) — lookup fresh dari DB |
✅ | lib/auth-guards.ts |
| 2.5 | Wire requireActiveUser di createTripAction + joinTripAction |
✅ | features/trip/actions.ts |
| 2.6 | Filter trip public list: organizer: { suspended: false } di findOpen |
✅ | server/repositories/trip.repo.ts |
| 2.7 | UI: tombol Suspend/Unsuspend di /admin/users/[id] dengan modal reason wajib |
✅ | features/admin/components/suspend-user-button.tsx |
| 2.8 | Badge "SUSPENDED" di user list + detail header (red border accent) | ✅ | list & detail pages |
| 2.9 | Server actions suspendUserAction + unsuspendUserAction (guard isAdmin) |
✅ | features/admin/actions.ts |
Tindakan manual ops:
- Apply migration:
npx prisma migrate deploy. - Brief admin: kriteria suspend (scam, harassment, repeated TOS violation). Reason wajib min 10 char.
- Wire
requireActiveUserke action mutating lain saat dibuat (createReviewAction, dst). - Pertimbangkan: bikin halaman info "Akun ditangguhkan" untuk UX saat suspended user coba login.
Phase 3 — User Analytics ⏳ (deferred)
Skip sampai growth team minta. Lihat versi awal di ADMIN_ROADMAP.md.