TTMT.ManageWebGUI/SYSTEM_ADMIN_PRIORITY_GUIDE.md

250 lines
5.6 KiB
Markdown

# 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`)
```typescript
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.
```typescript
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).
```typescript
if (hasHigherOrEqualPriority(userPriority, requiredPriority)) {
// User có đủ quyền
}
```
#### `getPriorityLabel(priority: number): string`
Lấy nhãn mô tả cho priority.
```typescript
getPriorityLabel(0) // "System Admin (Highest)"
getPriorityLabel(5) // "Priority 5"
```
---
### 3. useAuth Hook (`src/hooks/useAuth.tsx`)
Thêm method mới: `isSystemAdmin()`
```typescript
const { isSystemAdmin } = useAuth();
if (isSystemAdmin()) {
// User là System Admin (priority = 0)
console.log('You have highest permission!');
}
```
**Interface cập nhật:**
```typescript
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:
```typescript
// 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_ALL` trong database
---
## Cách sử dụng
### Kiểm tra System Admin trong component
```typescript
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ụ
```typescript
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
```typescript
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
```typescript
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
```typescript
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
1.`src/config/constants.ts` - Constants mới
2.`src/helpers/roleHelpers.ts` - Helper functions
3.`src/hooks/useAuth.tsx` - Thêm isSystemAdmin()
4.`src/types/auth.ts` - Cập nhật interface
5.`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!