Files
solution-erp/.claude/workflows/runs/2026-07-29-S161-khkk-w1-schema/sub-reviewer-2.md
2026-07-29 19:48:33 +07:00

3.2 KiB
Raw Blame History

SUB-REVIEWER — W1 KHKK adversarial diff review (S161, 2026-07-29)

Ghi-đĩa-TRONG-lúc-làm (chống #53 — 3 vai trước chết trong wave này). File = thứ sống sót. Scope: toàn bộ M/?? trong git status (trừ .claude/). 12 file M (+990/19) + 20 file ?? (~8.2K dòng, trong đó Designer.cs 6.960 = sinh máy). KHÔNG phủ lại: FK/index/maxLength/parity 2 DB (database-agent 8/8) · fault-inject test (test-specialist 4 test) · suite 566/0 + build 0W/0E (lead).

TIẾN TRÌNH

  • Trục 1 — seeder SeedKeHoachKyKetAccessAsync (5 sub-check a→e)
  • Trục 5 — MenuKeys.All (vị trí + tác dụng phụ)
  • Trục 2 — CodeGenerator twin-diff + DI
  • Trục 3 — 3 site AWV2AdminFeatures + grep-cùng-lớp
  • Trục 4 — FE containment 2 lớp
  • Trục 6 — boundary

TRỤC 1 — Seeder (DbInitializer.cs)

(a) Call-site thứ tự — PASS. RevokeTemporarilyHiddenModulesAsync :2096SeedProcurementMasterAccessAsync :2102SeedKeHoachKyKetAccessAsync :2109. Đứng SAU revoke ⇒ thắng revoke. Cũng SAU SeedAllRolesReviewReadPermissionsAsync :2089 (nhánh read-only skip-existing) ⇒ không bị nhánh nào hạ cờ về sau. Không có seeder nào chạy sau :2109 (2 call S65/S69 đã comment-out :2119/:2128).

(e) Revoker KHÔNG phủ Khkk_/KeHoachKyKet — PASS (rủi ro 2-chiều gotcha #84 KHÔNG hiện thực). Đọc thân RevokeTemporarilyHiddenModulesAsync:2296-2310: predicate CHỈ 3 nhánh MenuKey.StartsWith("Hrm") || StartsWith("Off") || == MenuKeys.Personal. Nhánh S92 (Contracts/Master/Catalog) đã GỠ @S159. Không prefix nào ăn Khkk_* hay KeHoachKyKet ⇒ grant không bị lật ở restart kế. (Ghi chú: thứ tự :2109 sau :2096 vẫn giữ đúng phòng khi revoker sau này mở rộng prefix.)

(b) UPGRADE-if-exists — PASS. :2414-2470: existing.TryGetValue((role.Id,key), out row) → nâng từng cờ if(!row.CanX)continue; nhánh else db.Permissions.Add(...) chỉ chạy khi row CHƯA có (fresh DB). Đúng khuôn SeedProcurementMasterAccessAsync:2375-2394, KHÔNG phải insert-only NO-OP (F-S1 đóng). Khác khuôn gốc 2 điểm CÓ CHỦ ĐÍCH: (i) key dictionary là tuple (RoleId, MenuKey) vì quét 13 role thay vì 1 → đúng, vì .Where(p => keys.Contains(p.MenuKey)) không lọc role nên ToDictionary(p => p.MenuKey) kiểu cũ sẽ ném ArgumentException trùng khoá — implementer tránh được bẫy này; (ii) thêm vế CanDelete.

(c) CanDelete chỉ Drafter+Admin, KHÔNG hạ cờ — PASS. allowDelete = role.Name == AppRoles.Admin || role.Name == AppRoles.Drafter. Mọi phép gán đều dạng if (!row.CanX) row.CanX = true ⇒ monotonic tăng, 0 câu nào set = false trên nhánh update. Nhánh insert đặt CanDelete = allowDelete (role khác = false) — đúng.

(d) 7 key khớp bộ seed menu-row — PASS (so từng chuỗi). Seeder :2419-2424 = MenuKeys.KeHoachKyKet + Khkk_WfView, Khkk_List, Khkk_Create, Khkk_Pending, Khkk_Approved, Khkk_Deleted. Menu-row :1779-1786 = Khkk_G1 + đúng 6 chuỗi trên. Khkk_G1 CỐ Ý loại (group điều hướng, CanRead-all đã có) — khai trong comment :2417-2418. 0 typo.