5.6 KiB
5.6 KiB
System Admin Priority Logic - Hướng dẫn
Tổng quan
Đã cập nhật logic để System Admin (Priority = 0) trở thành quyền cao nhất trong hệ thống.
Quy tắc Priority
Priority càng thấp = Quyền càng cao
Priority = 0 (System Admin) = Quyền cao nhất
Các thay đổi đã thực hiện
1. Constants mới (src/config/constants.ts)
export const SYSTEM_ADMIN_PRIORITY = 0;
export const RolePriority = {
SYSTEM_ADMIN: 0,
} as const;
Mục đích: Định nghĩa giá trị priority của System Admin, tránh hardcode số 0 trong code.
2. Helper Functions (src/helpers/roleHelpers.ts)
isSystemAdminPriority(priority: number): boolean
Kiểm tra xem priority có phải là System Admin không.
import { isSystemAdminPriority } from '@/helpers/roleHelpers';
if (isSystemAdminPriority(userPriority)) {
// User là System Admin
}
hasHigherOrEqualPriority(priority1, priority2): boolean
So sánh 2 priority (nhỏ hơn = cao hơn).
if (hasHigherOrEqualPriority(userPriority, requiredPriority)) {
// User có đủ quyền
}
getPriorityLabel(priority: number): string
Lấy nhãn mô tả cho priority.
getPriorityLabel(0) // "System Admin (Highest)"
getPriorityLabel(5) // "Priority 5"
3. useAuth Hook (src/hooks/useAuth.tsx)
Thêm method mới: isSystemAdmin()
const { isSystemAdmin } = useAuth();
if (isSystemAdmin()) {
// User là System Admin (priority = 0)
console.log('You have highest permission!');
}
Interface cập nhật:
export interface IAuthContext {
// ... các field cũ
isSystemAdmin: () => boolean; // ← Mới
}
4. Sidebar Logic (src/components/sidebars/app-sidebar.tsx)
Cập nhật logic kiểm tra admin:
// TRƯỚC
const isAdmin = acs.includes(PermissionEnum.ALLOW_ALL);
// SAU
const isAdmin = acs.includes(PermissionEnum.ALLOW_ALL) || isSystemAdmin();
Lợi ích:
- System Admin (Priority = 0) thấy tất cả menu items
- Không cần phải có permission
ALLOW_ALLtrong database
Cách sử dụng
Kiểm tra System Admin trong component
import { useAuth } from '@/hooks/useAuth';
function MyComponent() {
const { isSystemAdmin, role } = useAuth();
return (
<div>
{isSystemAdmin() && (
<AdminOnlyFeature />
)}
<p>Role: {role.roleName}</p>
<p>Priority: {role.priority}</p>
</div>
);
}
Kiểm tra priority trong logic nghiệp vụ
import { isSystemAdminPriority, hasHigherOrEqualPriority } from '@/helpers/roleHelpers';
function canDeleteUser(currentUserPriority: number, targetUserPriority: number): boolean {
// System Admin có thể xóa bất kỳ ai
if (isSystemAdminPriority(currentUserPriority)) {
return true;
}
// User chỉ có thể xóa user có priority thấp hơn (số lớn hơn)
return hasHigherOrEqualPriority(currentUserPriority, targetUserPriority);
}
Hiển thị label priority
import { getPriorityLabel } from '@/helpers/roleHelpers';
<Badge>{getPriorityLabel(role.priority)}</Badge>
// System Admin sẽ hiển thị: "System Admin (Highest)"
Luồng kiểm tra quyền
User đăng nhập
↓
Priority được lưu vào localStorage
↓
useAuth hook load priority
↓
isSystemAdmin() kiểm tra priority === 0
↓
Sidebar check: ALLOW_ALL || isSystemAdmin()
↓
Hiển thị menu items phù hợp
Ví dụ thực tế
Ví dụ 1: Ẩn/hiện nút Delete dựa trên priority
function UserManagement() {
const { role, isSystemAdmin } = useAuth();
const currentUserPriority = role.priority;
function canDelete(targetUserPriority: number): boolean {
// System Admin xóa được tất cả
if (isSystemAdmin()) return true;
// Priority thấp hơn (số nhỏ hơn) mới xóa được
return currentUserPriority < targetUserPriority;
}
return (
<Table>
{users.map(user => (
<TableRow key={user.id}>
<TableCell>{user.name}</TableCell>
<TableCell>
{canDelete(user.role.priority) && (
<DeleteButton userId={user.id} />
)}
</TableCell>
</TableRow>
))}
</Table>
);
}
Ví dụ 2: Route protection
import { useAuth } from '@/hooks/useAuth';
import { redirect } from '@tanstack/react-router';
export const Route = createFileRoute('/_auth/admin-panel')({
beforeLoad: ({ context }) => {
const { isSystemAdmin } = context.auth;
if (!isSystemAdmin()) {
throw redirect({
to: '/unauthorized',
});
}
},
component: AdminPanel,
});
Tóm tắt
✅ Priority = 0 là System Admin (quyền cao nhất)
✅ Priority thấp hơn = Quyền cao hơn
✅ Có constants và helpers để tái sử dụng
✅ isSystemAdmin() method trong useAuth hook
✅ Sidebar tự động nhận biết System Admin
✅ Không cần hardcode giá trị priority nữa
Files đã thay đổi
- ✅
src/config/constants.ts- Constants mới - ✅
src/helpers/roleHelpers.ts- Helper functions - ✅
src/hooks/useAuth.tsx- Thêm isSystemAdmin() - ✅
src/types/auth.ts- Cập nhật interface - ✅
src/components/sidebars/app-sidebar.tsx- Logic admin check
Lưu ý quan trọng:
Backend cũng cần implement logic tương tự để đảm bảo consistency giữa frontend và backend!