--- name: permission-matrix description: Hệ thống phân quyền Role × MenuKey × CRUD. Sidebar gating, permission guard, seed default, reset password. Dùng khi debug access denied, gán role, menu không hiện. when-to-use: - "permission denied" - "access denied" - "menu không hiện" - "gán role cho user" - "reset password" - "seed permission" --- # Permission Matrix Skill > **Phase 1 deliverable.** Hiện tại skill này là PLACEHOLDER. ## Context Pattern copy từ **NamGroup** skill `permission-system` nhưng đơn giản hóa: - 1 User có N Role - 1 Role có ma trận (MenuKey, CRUD flags) — `Permission` table - Không có per-user override (giữ đơn giản cho Phase 1) - Menu tree flat 2 cấp, hardcode `MenuKey` ## Tech - BE: `[Authorize(Policy = "Menu.Read")]` attribute - FE: `` + `usePermission().can("Contracts", "Update")` - Resolution: API `/api/menus/me` trả về tree + permissions đã resolved theo user's roles ## Code pointers (sẽ có sau Phase 1) - `src/Backend/SolutionErp.Domain/Identity/Permission.cs` - `src/Backend/SolutionErp.Application/Permissions/Queries/GetMyMenuTreeQuery.cs` - `fe-admin/src/components/PermissionGuard.tsx` - `fe-admin/src/hooks/usePermission.ts` ## Common pitfalls (dự kiến) - Quên refresh token sau khi admin update permission → user phải logout/login mới thấy - MenuKey hardcode dễ typo → tập trung vào file `src/lib/menuKeys.ts` (FE) + `MenuKeys.cs` (BE const)