# sub-reviewer-cum — Review ADVERSARIAL cụm W3+W4+W5+W6 (YC-024/025) TRƯỚC push

**Run:** `2026-08-10-S187-duyet-hd-tu-khkk` · **Vai:** reviewer (adversarial, verdict-only, KHÔNG sửa code)
**Ngày:** 2026-08-10 · **Relaunch** (lượt trước chết 0-trace)

## Đề bài tóm

Soi diff `git diff` + untracked (20 file) trước push. Trọng tài đã xanh: full test 680/680, build FE ×2 OK, 0 Migrations mới.

Trục rủi ro lead giao:
1. 🔴 Seeder W3 chạy thẳng prod (#51): `SeedContractTypeWorkflowsAsync` idempotent per-Code; roster builder `applyLevel2Finalize:false` cho họ HD; KHKK sau refactor GIỮ NGUYÊN (`true`); menu-row 7 key seed được trên DB prod CŨ hay chỉ DB mới?
2. 🔴 Guard W4: 4 cửa đủ; backward-compat (V1 + mã-ngoài-họ chỉ chặn pin MỚI); message giữ 2 chuỗi test cũ; UpdateDraft field cuối; vì sao `ContractSigningPlansController.cs` đổi.
3. 🔴 Đ2 W6-BE: V2 sai-trạm bị chặn thật; V1 giữ nguyên; DaPhatHanh bất khả xâm phạm.
4. FE: card Nguồn-gốc null-safe; panel 2-nút gating OR-of-N; dual-render V1; Designer type-3 slice; `contractWorkflowFamily.ts` nguồn-đôi 7 mã vs BE; SHA-pair; unused/CS8019.
5. STATUS 2 row đúng số đếm; 0 secret; tiếng Việt.

**Diff scope đo được:** 15 file modified (+1223 / −137) + 6 file untracked.

---

## Nhật ký đo (append theo mục)

### 🔴 C-1 (BLOCKER) — 7 leaf menu `AwV2_Hd*` DROP IM LẶNG khỏi sidebar (gotcha #50, Pattern 16-bis "chỗ thứ 4")

**Đo:**
- `git status --porcelain fe-admin/src/components/Layout.tsx` → **RỖNG** (file KHÔNG đổi trong cụm này).
- `grep -n "contractWorkflowFamily|findContractWfByTypeCode|Hd" fe-admin/src/components/Layout.tsx` → **0 hit**.
- Control dương cùng lệnh: `grep -n "AwV2_"` cùng file → hit `:175` `key.match(/^AwV2_(.+)$/)` + `:187` `/^KhkkN[1-8]$/` ⇒ thước sống, 0-hit là **vắng THẬT**.
- `Layout.tsx:30` `resolvePath` nhánh `AwV2_`: chỉ nhận `DuyetNcc` · `DuyetNccPhuongAn` · `Contract` · `/^KhkkN[1-8]$/`. `AwV2_HdTP` → rơi xuống `return null`.
- `Layout.tsx:331-335` `MenuLeaf`: `const path = resolvePath(node.key); if (!path) return null` ⇒ leaf biến mất **không báo lỗi**.

**Hệ quả:** BE seed 7 menu-row + 28 policy vào DB (kể cả prod, seeder ungated); admin thấy… **không gì cả** dưới "Quy trình duyệt (Mới)". Panel Designer 7 loại (đã viết ở `ApprovalWorkflowsV2Page.tsx:310-420`) **chỉ tới được bằng gõ tay URL** `/system/approval-workflows-v2/HdTP`. Đây đúng lớp "máy dựng mà không ai gọi".

**Bằng chứng lời-hứa-chưa-land (file MỚI tự khai):** `fe-admin/src/lib/contractWorkflowFamily.ts:6-11` viết *"Có ĐÚNG HAI chỗ đọc … 2. `components/Layout.tsx` `resolvePath` — đổi menu-key `AwV2_Hd*` thành đường dẫn ("chỗ thứ 4" Pattern 16-bis; thiếu là leaf DROP IM LẶNG khỏi sidebar — gotcha #50)"*. `grep -rn "contractWorkflowFamily" fe-admin/src fe-user/src` → **chỉ 1 importer** (`ApprovalWorkflowsV2Page.tsx:39`). Consumer #2 mà chính file khai = **chưa tồn tại**.

**AC để đóng:** thêm nhánh vào `resolvePath` (khuôn `/^KhkkN[1-8]$/` `:187`) dùng `findContractWfByTypeCode(code) !== null` ⇒ `return '/system/approval-workflows-v2/' + code`; kiểm bằng đếm 7 `<NavLink>` con dưới root `ApprovalWorkflowsV2` sau khi seed (control âm: `HdXX` bịa phải vẫn null).

### C-2 (MAJOR) — mirror `menuKeys.ts` ×2 app thiếu 7 key mới

`grep -rn "AwV2_" fe-admin/src/lib/menuKeys.ts fe-user/src/lib/menuKeys.ts` → có đủ 10 key cũ (`AwV2_DuyetNcc`, `AwV2_DuyetNccPhuongAn`, `AwV2_KhkkN1..N8`) nhưng **0 key `AwV2_Hd*`**. Tiền lệ ngay trong file (`fe-admin/src/lib/menuKeys.ts:34-38`) khai rõ lý do phải chép cả key chưa có call-site: *"chép vào để bảng đối chiếu FE↔BE không khuyết, tránh lượt sau đọc chỗ này rồi kết luận 'BE chưa có key nhóm'"*. Bỏ 7 key = tái lập đúng cái bẫy mà chú thích đó dựng để chặn. Không chặn build (chỉ là bảng tra), nên MAJOR không BLOCKER.

### ✅ SHA-pair 3 cặp FE mirror — ĐẠT (đo `sha256sum`, 16 ký tự đầu)

| Cặp | sha (16) | KQ |
|---|---|---|
| `ContractWorkflowPanel.tsx` admin/user | `9cdf9ffe649dbc5d` | ✅ identical |
| `ContractDetailContent.tsx` admin/user | `cd81508f97cb79fc` | ✅ identical |
| `ContractCreatePage.tsx` admin/user | `17edc625ddc9654b` | ✅ identical |

`contractWorkflowFamily.ts` **fe-admin only** — KHÔNG-CẶP có chủ đích, khai tại `:16-18` (fe-user 0 route Designer). Đo xác nhận: `ls fe-user/src/lib/contractWorkflowFamily.ts` → không tồn tại. Hợp lệ.

