[CLAUDE] FE-Admin: K6 SP-002 admin thu gon menu 12-key ADMIN_HIDDEN_KEYS + comment lineage 2-dao (gate PASS-WITH-FLAGS 5)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 6m28s

C1 15-la liet ten 16/16 assert + control-am 15->63; C2 fe-user 0-diff; C4 display-only #82.
Gate MAJOR-1 fixed truoc commit: bo 3 so-dem trong comment (28-leaf da SAI luc land; luat #84).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-08-01 11:54:30 +07:00
parent d82c5a8175
commit 1c6d77a6cc

View File

@ -191,26 +191,61 @@ function resolvePath(key: string): string | null {
return null return null
} }
// Admin side: hide the per-ContractType contract submenu (Ct_*) — that's a // ============================================================================
// user-app concern. Keep Wf_* workflow-admin leaves. // [K6 — S166 2026-08-01, QĐ7] ADMIN THU VỀ VAI "NƠI-CONFIG"
// [S57] BỎ ẩn "Danh mục" (Master/Catalogs + Cấu hình HRM re-parent vào đây) — gom // ============================================================================
// master data về 1 ch cho CẢ admin lẫn nhân viên (đảo S29 hide). Admin nay quản // Sidebar fe-admin ch còn: Tổng quan · Hệ thống (Người dùng / Vai trò / Phân
// master trực tiếp trên fe-admin; write vẫn khóa Admin/CatalogManager ở BE controller. // quyền / Menu eOffice, cùng nhánh con "Quy trình duyệt (Mới)" + toàn bộ Designer).
// 🔴 [K4a — S166, vá-8] RÀNG BUỘC NGƯỢC với `resolvePath` bên trên — đọc trước khi // Mọi module NGHIỆP VỤ (4 giai đoạn HĐ, Duyệt NCC, Danh mục, HRM, Văn phòng…)
// sửa bộ lọc này. fe-user có nhánh regex `^Khkk_G([1-8])_(WfView|List|Create|Pending| // làm việc ở fe-user; admin không phải là chỗ chạy nghiệp vụ nữa.
// Approved|Deleted)$`; fe-admin CỐ Ý KHÔNG có (admin không có `WorkflowMatrixViewPage` //
// — lead chốt 2026-07-27, giữ lệch). Hệ quả: 42 leaf `Khkk_G{2..8}_*` mà BE seed sẽ // 🔴 LỊCH SỬ ĐÃ ĐẢO 2 LẦN — đọc kỹ trước khi "sửa cho đúng":
// rơi vào `resolvePath → null` ⇒ MenuLeaf trả null ⇒ DROP IM LẶNG (gotcha #50). // · S29 : ẩn "Danh mục" khỏi admin.
// ⚠️ ĐO ĐĨA 2026-08-01: hàm này CHỈ ẩn `Ct_*` — `KeHoachKyKet` KHÔNG hề nằm trong tập // · S57 : BỎ ẩn — gom master data về 1 chỗ cho cả admin lẫn nhân viên, admin
// ẩn, tức ràng buộc trên KHÔNG phải chuyện tương lai mà ĐANG hiệu lực: sidebar admin // quản master trực tiếp trên fe-admin. (Đảo lần 1.)
// hiện root KHKK, 7 nhóm con, và 42 leaf của nhóm 2..8 im lặng biến mất (nhóm 1 sống // · S164 : QĐ7 ẩn LẠI, lần này ẩn rộng hơn hẳn — admin thu về vai NƠI-CONFIG.
// nhờ 6 dòng `Khkk_*` không-infix trong `staticMap`). Đây là trạng thái ĐÃ KHAI, chấp // (Đảo lần 2, chính là luật đang chạy dưới đây.)
// nhận có chủ đích ở lượt K4a — KHÔNG phải bug mới phát sinh. // ⇒ Comment cũ của S57 nay KHÔNG còn hiệu lực. Ai đọc lịch sử git thấy hai
// ⇒ Ai muốn admin thấy đủ 8 nhóm (hoặc ngược lại, thêm `KeHoachKyKet` vào tập ẩn rồi // lời ngược nhau thì đây là chỗ giải thích: cả hai đều từng đúng, mốc sau
// sau đó gỡ ra) thì PHẢI nới regex `Khkk_G*` trong `resolvePath` TRƯỚC — và nới thì // thắng mốc trước. Đừng "khôi phục" S57 vì tưởng gặp bug.
// phải quyết luôn `WfView` bên admin trỏ đâu, vì Designer không nhận `?group=`. //
// 🔴 ĐÂY LÀ LỚP HIỂN THỊ, KHÔNG PHẢI LỚP QUYỀN (2 tầng độc lập — gotcha #82):
// Route fe-admin còn nguyên, quyền của tài khoản admin còn nguyên ⇒ deep-link
// thẳng `/purchase-evaluations`, `/khkk/list`… VẪN vào được và API vẫn trả 200.
// Thu gọn ở đây = bớt lối đi trên menu, KHÔNG phải thu hồi quyền. Muốn CHẶN
// thật thì phải làm ở BE authz (`[Authorize(Policy=…)]`), không phải ở file này.
//
// 🔴 CƠ CHẾ: `filterForAdmin` lọc ĐỆ QUY mọi tầng ⇒ ẩn 1 root là cả cây con chết
// theo. Vì vậy tập dưới chỉ liệt ROOT (+2 nhánh con của `System`), KHÔNG liệt
// từng leaf — liệt leaf vừa thừa vừa phải bảo trì lại mỗi lần BE thêm key.
// Hệ quả phụ (tốt): các leaf `Khkk_G{2..8}_*` không còn được render bên admin
// nên chuyện `resolvePath` thiếu nhánh `Khkk_G*` (khai ở K4a) hết là vấn đề —
// nay chúng bị cắt từ tầng cha chứ không "rơi im lặng" ở tầng leaf nữa.
// ⚠️ Nếu sau này gỡ `KeHoachKyKet` khỏi tập này thì PHẢI nới regex `Khkk_G*`
// trong `resolvePath` TRƯỚC, kèm quyết định `WfView` admin trỏ đâu (admin
// không có `WorkflowMatrixViewPage`; Designer không nhận `?group=`).
const ADMIN_HIDDEN_KEYS = new Set<string>([
'PurchaseEvaluations', // GĐ1 root — Pe_* chết theo
'KeHoachKyKet', // GĐ2 root — toàn bộ nhánh Khkk_G* chết theo
'Contracts', // GĐ3 root — Ct_* vốn đã có luật prefix, nay ẩn cả root
'HopDongCung', // GĐ4 root — Hdc_* chết theo
'Forms',
'Reports',
'Master', // Danh mục root — Suppliers/Projects/Departments/Catalogs + Cấu hình HRM chết theo
'Hrm',
'Off',
'Personal',
'Workflows', // CON của System ⇒ phải liệt riêng (Wf_* chết theo)
'PeWorkflows', // CON của System ⇒ phải liệt riêng (PeWf_* chết theo)
])
function isAdminHidden(key: string): boolean { function isAdminHidden(key: string): boolean {
return key.startsWith('Ct_') // `Ct_*` giữ luật prefix cũ: leaf hợp đồng theo loại là chuyện của app người
// dùng. Thừa so với việc ẩn root `Contracts` ở trên, nhưng giữ để một ngày
// nào đó mở lại root thì đám leaf `Ct_*` không ùa về theo. (KHÔNG ghi số lá
// ở đây — số-đếm trong comment thối ngay khi BE thêm key [bài #84]; cần số
// thì grep `Ct_` trong MenuKeys.cs phía BE.)
return ADMIN_HIDDEN_KEYS.has(key) || key.startsWith('Ct_')
} }
function filterForAdmin(nodes: MenuNode[]): MenuNode[] { function filterForAdmin(nodes: MenuNode[]): MenuNode[] {