Files
setrip/docs/archive/ADMIN_USER_MGMT_ROADMAP.md
T

60 lines
4.2 KiB
Markdown

# Setrip — Admin User Management Roadmap (ARCHIVED — DELIVERED 2026-05-18, fully done)
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 | ✅ Delivered | Page `/admin/users/stats` dengan stats card (total/suspended/verified-organizer/active-organizer-30d/paid-participant-30d) + bar chart signup per minggu (8 minggu terakhir, inline SVG-free). |
---
## Phase 1 — User List & Detail ✅
| # | Item | Status | File |
|---|---|---|---|
| 1.1 | `userRepo.searchForAdmin({ q?, suspended? })` | ✅ | [server/repositories/user.repo.ts](../../server/repositories/user.repo.ts) |
| 1.2 | Page `/admin/users` — list + search + tab filter (ALL/ACTIVE/SUSPENDED) | ✅ | [app/admin/users/page.tsx](../../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](../../app/admin/users/[id]/page.tsx) |
| 1.4 | Stats cards: trip dibuat, booking aktif, total spent (PAID) | ✅ | [app/admin/users/[id]/page.tsx](../../app/admin/users/[id]/page.tsx) |
| 1.5 | Link "Users" di admin navbar | ✅ | [components/admin/admin-sidebar.tsx](../../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](../../server/services/user.service.ts) |
| 2.3 | Block sign-in di NextAuth `signIn` callback (email-based, jalan untuk Credentials + OAuth) | ✅ | [lib/auth.ts](../../lib/auth.ts) |
| 2.4 | Helper `requireActiveUser(userId)` — lookup fresh dari DB | ✅ | [lib/auth-guards.ts](../../lib/auth-guards.ts) |
| 2.5 | Wire `requireActiveUser` di `createTripAction` + `joinTripAction` | ✅ | [features/trip/actions.ts](../../features/trip/actions.ts) |
| 2.6 | Filter trip public list: `organizer: { suspended: false }` di `findOpen` | ✅ | [server/repositories/trip.repo.ts](../../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](../../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](../../features/admin/actions.ts) |
**Tindakan manual ops:**
1. Apply migration: `npx prisma migrate deploy`.
2. Brief admin: kriteria suspend (scam, harassment, repeated TOS violation). Reason wajib min 10 char.
3. Wire `requireActiveUser` ke action mutating lain saat dibuat (`createReviewAction`, dst).
4. Pertimbangkan: bikin halaman info "Akun ditangguhkan" untuk UX saat suspended user coba login.
---
## Phase 3 — User Analytics ✅
| # | Item | Status | File |
|---|---|---|---|
| 3.1 | Stats: total users, suspended, verified organizers, active organizer 30d (bikin trip), paid participant 30d | ✅ | [app/admin/users/stats/page.tsx](../../app/admin/users/stats/page.tsx) |
| 3.2 | Bar chart signup per minggu (8 minggu terakhir, pakai inline div height % — no chart library) | ✅ | [app/admin/users/stats/page.tsx](../../app/admin/users/stats/page.tsx) |
| 3.3 | Link "📊 Stats" di header `/admin/users` | ✅ | [app/admin/users/page.tsx](../../app/admin/users/page.tsx) |