feat(management): add user management and role-based navigation #171
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/170-user-management"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #170
What changed
DashboardNavwith neutral "Pengaturan" trigger button, desktop drop-up popover, mobile settings drawer, and conditional "Manajemen Pengguna" link for admins./settings/usersadmin user management page with metric cards (Total, Admin, Manager, Operator), search bar, role filter pills, responsive "Tambah Pengguna" button, full user table, and modals for Add User, Edit User, and Reset Password.server.tsandschema.tsto supportroleattribute with defaultoperator.0015_add_user_role.sqlmigration to add role column tousertable and update existing seed accounts.requireAdminandrequireRoleguards tolib/auth/guard.ts.Verified
pnpm --filter garage testpassed (27 test files, 515 tests passed).pnpm --filter garage typecheckpassed (0 errors)..forgejo/scripts/biome-gate.shpassed (0 new findings against baseline).Round 1 Addressed
input: falseforuser.additionalFields.roleinserver.tsso public callers cannot self-assign roles.createUserActionandupdateUserActionrejecting already-linked numbers with clear error.updateUserActionto upsert phone identity without unlinking other verified numbers.createUserActionto return the real persisted UUID and updated client state accordingly./dashboard redirect to/stokfor operator role and filtered out "Dasbor" from navigation items.getUsers()to only query verified WhatsApp identities.crypto.getRandomValues()for secure random password generation.All verifications passed (
test,typecheck,biome-gate). Ready for re-review.VERDICT: approve
All Round 1 review findings have been resolved satisfactorily, and all acceptance criteria are met:
input: falseonuser.additionalFields.role)./stokredirect and navigation filtering.crypto.getRandomValues) is used for password generation.VERDICT: request-changes
apps/management/lib/users/actions.ts:L269: should: Editing or clearing a WhatsApp number leaves the old verified identity active, so the previous phone still authorizes bot access and the displayed number can revert on refresh. Replace/unlink the previous identity in the transaction when the phone changes, preserving other linked numbers only if explicitly supported.
apps/management/app/(dashboard)/settings/users/user-management-client.tsx:L524: should: The table promises operators no financial dashboard, but /laporan still exposes revenue/profit reports to any signed-in operator via direct URL. Guard the report page and its data sources for admin/manager, or correct the stated module permissions if access is intended.
apps/management/app/(dashboard)/settings/users/user-management-client.tsx:L1008: should: On phone-height screens the fixed, centered add/edit/reset modal cards have no max-height or vertical scroll, making bottom submit controls unreachable. Constrain dialog height to the viewport and scroll its content.
Reviewed branch feat/170-user-management at
14420e2; auth role input is now server-controlled and the create-user response is wired correctly.VERDICT: request-changes
Additional finding for the PR head currently on Forgejo (
b828e0e; local feat/170-user-management is ahead at14420e2):apps/management/lib/auth/server.ts:L43: blocker: The role additional field has input: true, and the public Better Auth POST /api/auth/sign-up/email and authenticated POST /api/auth/update-user accept writable additional fields; anyone can sign up as admin or an existing operator can update their own role to admin, bypassing every requireAdmin guard. Set input: false and assign roles only in the guarded admin actions.
The local
14420e2revision already contains this fix, but Forgejo still points atb828e0eat review submission; push the corrected revision before merging.Merged to main in squash commit ea97cf3c6178e6c738ef9188092ec06f0e4b37d2.