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

28 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
- [x] Trục 1 — seeder `SeedKeHoachKyKetAccessAsync` (5 sub-check a→e)
- [x] 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` `:2096``SeedProcurementMasterAccessAsync` `:2102`**`SeedKeHoachKyKetAccessAsync` `: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.