# Spesifikasi & implementasi: manajemen user (superadmin)

Spesifikasi produk asli: [`../FE/docs/BE_SPEC_ADMIN_USER_MANAGEMENT.md`](../FE/docs/BE_SPEC_ADMIN_USER_MANAGEMENT.md).

## Yang diimplementasikan (BE)

Semua di bawah **`authMiddleware`** + **`requireSuperadmin`** (JWT `role` harus `superadmin`).

| Method | Path | Fungsi |
|--------|------|--------|
| `GET` | `/api/v1/admin/users` | Query: `limit` (1–100, default 20), `offset`, `q` (cari email/nama, ILIKE). Respons: `{ users, total }`. |
| `POST` | `/api/v1/admin/users` | Body: `email`, `password` (min 8), `name`, `role` (`superadmin` \| `user`). Bcrypt cost sama seperti register. |
| `GET` | `/api/v1/admin/users/:id` | Detail (tanpa `password_hash`). |
| `PATCH` | `/api/v1/admin/users/:id` | Partial: `name`, `role`, `isActive`. Email tidak diubah. |

**Tidak** diimplementasikan (fase 2): `POST /admin/users/:id/reset-password`.

## Aturan bisnis

- Role hanya **`superadmin`** atau **`user`** (case-insensitive di input, disimpan lowercase).
- Email disimpan **lowercase** seperti login/register.
- Tidak boleh menurunkan / menonaktifkan user jika itu **superadmin aktif terakhir** → **400** `validation` + pesan jelas.

## Error HTTP

| Situasi | HTTP | `error.code` |
|---------|------|----------------|
| Bukan superadmin | 403 | `forbidden` |
| Token invalid / hilang | 401 | `unauthorized` |
| Email duplikat | 409 | `duplicate` |
| Body / role invalid | 400 | `validation` |
| User tidak ada | 404 | `not_found` |

## File kode

- `internal/api/admin_users.go` — handler.
- `internal/api/server.go` — `requireSuperadmin`.
- `internal/api/router.go` — grup `/admin`.

Setelah ubah kode: `go build -o bin/api ./cmd/api/` lalu **`pm2 delete workpulse-api && pm2 start ecosystem.config.cjs`** (atau setara) agar binary dan env terbaru.
