Files
solution-erp/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-cum2-chi-tiet-31-07-2026.md
2026-07-31 14:20:44 +07:00

5.7 KiB
Raw Blame History

SPEC CỤM-2 FINAL — K4 + K5 + K6 (lead kết tinh sau B2-r cụm-2, @S164)

① Đề bài

K4 sidebar 8 nhóm × 6 leaf (49 row menu mới) · K5 cây sub-folder groups · K6 admin thu gọn 12-key. NỀN = sub-invest-fable-b2-cum2.md (5/5 section, 0-mig) — 15 VÁ dưới thắng khi xung đột (từ sub-reviewer-c2-l{1,2}.md; ⚠️ lane c2-l3 chết ruột 188B — lens đo-được/thứ-tự phủ bù bằng overlap L1-F2/F6 + L2-H2/H3/M4 + lead-note §④, KHAI RÕ không giấu).

② 15 vá

  1. 🔴 [L1-F2 L2-H2 hội tụ] Route regex resolvePath ship CÙNG K4a (tách khỏi K4c) — leaf không route bị if (!path) return null nuốt IM LẶNG (fe-user/Layout.tsx:336-338); không tách thì sau K4a: 7 group RỖNG + 42 leaf VÔ HÌNH by-construction. Chỉ mục WfView-lọc-theo-Code (Code==='KHKK-N'+n) mới thật sự chờ K3.
  2. 🔴 [L1-F6 L2-H3] Drift khai DELTA (+49 key / +196 policy), CẤM neo 2 mốc tuyệt đối (64→113 chỉ đúng nếu cụm-1 land trước — thứ tự ship đang cho song song); commit kèm lệnh đo lại MenuKeys.All thực tế.
  3. 🔴 [L2-H1] TanStack queryKey list PHẢI CHỨA group — thiếu thì 8 leaf dùng chung 1 ô cache = silent-wrong build xanh (đúng họ bài S159 2-khóa-cache).
  4. [L1-F4] SQL nghiệm thu N designer: JOIN MenuItems × Permissions × Roles(Admin, CanRead=1) — row tồn tại ≠ hiện sidebar (GetMyMenuTreeQuery.cs:96 lọc HasAccess); đo trên env nghiệm thu (prod), không phải Dev.
  5. [L2-M3] KhkkListPage derive phase từ searchParams (hiện useState mount-only :63-65, route không keyed ⇒ bấm leaf→leaf KHÔNG re-lọc; cùng file deletedView:61 đã đọc searchParams đúng — đồng bộ về 1 kiểu). ×2 app.
  6. [L2-M4] Trả "Thao tác/Create preset ?group=" VỀ K4b (0 phụ thuộc K3 — chỉ cần picker vá-4 cụm-1).
  7. [L2-M5] 8 nhãn menu ĐÍNH vào file OG-6 (danh-muc-sp002-transcribe.md) cho anh soát 1 lượt trước K4a + sửa nhãn N2 thiếu vế "phá dỡ" ("Kết cấu, hạ tầng, phá dỡ & DV hỗ trợ thi công"); nhãn đổi-sau-seed = +labelBackfill + restart (không phải sửa chữ tự do — comment DbInitializer.cs:1959-1961).
  8. [L2-M6 L1-F3] Ràng buộc ngược tại ADMIN_HIDDEN_KEYS: comment "gỡ KeHoachKyKet khỏi đây ⇒ PHẢI nới regex Layout.tsx fe-admin trước — 48 leaf sẽ drop im lặng #50". KHÔNG nới regex fe-admin đợt này (fe-admin thiếu WorkflowMatrixViewPage — nới sẽ đẻ leaf WfView chết trên admin; verified L1-BÁC-2).
  9. [L2-M7] Cây K5 HIỆN ĐỦ 8 sub-folder kể cả rỗng (mirror sidebar đúng nghĩa + tiền lệ prod: folder GĐ "SẮP" vẫn hiện) — bỏ đề xuất ẩn-nhóm-rỗng của lane; fallback "(chưa phân nhóm)" GIỮ cho phiếu NULL-group.
  10. [L2-M1] Sửa LÝ DO giữ site-2 (group-key KHÔNG cần CanRead row — HasAccess đệ quy theo con :96-97); kết luận giữ-3-site GIỮ NGUYÊN.
  11. [L2-M2] +1 dòng site-4 revoker: RevokeTemporarilyHiddenModulesAsync:2286 (gọi :2097 GIỮA site-2/3) prefix Hrm*/Off*/Personal — đã soi, 0 match Khkk; A5 restart ×2 là phép thử nó.
  12. [L1-F5] Acceptance label đo bằng SQL cột Label, DisplayLabel (fe-admin không đọc displayLabel — MenuItem.cs:12-13; fe-user effectiveLabel:204-206).
  13. [L1-F7] Vá comment stale DbInitializer.cs:1959-1961 (tự trỏ ":1893-1905" — thật :1926-1943) cùng diff K4a.
  14. [cụm-2 surprise] Viết lại comment fe-admin :179-181 ("S57 BỎ ẩn Danh mục" — QĐ7 đảo lần 2 cùng chỗ) cùng commit K6 — khai lineage 2 lần đảo.
  15. [precedent-split] Khai 2 khuôn menu-key trong doc K4: Ct_*/Pe_* CỐ Ý ngoài-All (comment :2193-2195) ⟂ catalog/AwV2/Khkk mới TRONG-All — người build đọc 1 khuôn đừng tưởng khuôn kia sai.

③ Checklist final cụm-2

  • K4a (ship 1 khối): 49 row menu VÀO All + labelBackfill G1 + route regex resolvePath ×(fe-user; fe-admin GHI RÀNG BUỘC) + 3-site grant (+dòng site-4 đã-soi) + nhãn N2 sửa + comment :1959/:179 vá. Acceptance: Admin + 1 user thường THẤY 8 group sidebar fe-user; 42 leaf BẤM ĐƯỢC (không null-route); drift DELTA khai + đo lại All; SQL JOIN đếm designer đúng N; restart ×2 số row menu/permission KHÔNG đổi (idempotent + revoker-proof).
  • K4b: 4 leaf list + Thao tác preset — derive phase+group từ searchParams; queryKey += group; acceptance bấm leaf→leaf ĐỔI kết quả không cần F5; URL G1 6 leaf mang group=1.
  • K4c (sau K3): WfView lọc Code==='KHKK-N'+n.
  • K5: groups mang leaves thật (không đường content) + GĐ2 by approvalGroup + GĐ3/4 by c.type + HIỆN ĐỦ 8 + fallback chưa-phân-nhóm + Σ sub-folder == tổng phiếu; SHA-identical 4 file pipeline ×2 app (lệnh đo từng file); build ×2 PASS. +forward-provision (B3-A5, việc cụm-3 vá-4b đẻ cho K5): builder GĐ3/GĐ4 nối qua TẬP lines[].contractId pe.contractId legacy — không thì HĐ thứ 2+ (OG-1 UI-1-1, N HĐ/PE) vô hình trên cây.
  • K6: blacklist 12-key tường minh + acceptance liệt kê ĐÚNG N mục lá (tên + đếm, dư/thiếu 1 = FAIL) + git diff --stat -- fe-user/src = 0 file + comment ràng-buộc-ngược land.
  • Test (lead-note bù L3): seed-menu idempotent ×2 · labelBackfill đổi-label-không-nhân-row · route-map FE có leaf nào null-path = FAIL (unit nhỏ nếu khuôn có; không thì acceptance tay + chụp). Baseline ≥590+k khai k.

END spec-cum2-final — nền K4 13v·K5 6v·K6 4v + 15 vá · 1 lane review chết ruột ĐÃ KHAI + phủ bù.