# sub-b6-w4-worker — W4 (YC-029, plan SOLTUON-12-08-2026)

Vai: implementer-frontend · File đích DUY NHẤT: `fe-admin/src/components/Layout.tsx`
Nguồn lệnh: `sub-b5-plan-final.md` block `### W4` (:37-48) + `## Điều kiện dừng` (:117-131).
INPUT phụ đã đọc: spec `:28-34` (§② W4) + `:98-100` (§③ W4) · style-gate §D `:83-87` (C-1a/C-2), `:101-103` (C-13), `:106-107` (C-5).

## Việc đã làm

**Tiền-đề đo tươi TRƯỚC khi sửa (Đ-5 — 0 lệch):**
- `fe-admin/src/components/Layout.tsx` — `if (awV2Match) {` = **:176** · nhánh KhkkN = **:188** · `}` đóng khối = **:189** ⇒ khớp mốc plan `:43` + C-13 `:103`.
- `fe-admin/src/lib/contractWorkflowFamily.ts` — `findContractWfByTypeCode` = **:77-80** (named export) · `CONTRACT_WF_FAMILY` = **:45** (7 member `HD-TP…HD-NT-DV`) · `contractWfTypeCode` = **:69** ⇒ khớp plan `:42`. Không lệch dòng nào ⇒ KHÔNG kích Đ-5.
- Baseline eslint fe-admin đo TRƯỚC sửa: **42 problems (37 errors, 5 warnings)**, exit 1 — đúng số pin của C-1a.

**Việc 1 — import named** (`Layout.tsx:9`, ngay sau `import { cn } from '@/lib/cn'`):
```
import { findContractWfByTypeCode } from '@/lib/contractWorkflowFamily'
```

**Việc 2 — nhánh TRONG khối `awV2Match`** (`Layout.tsx:195`, SAU nhánh KhkkN `:189` và TRƯỚC `}` `:196` — số dòng dịch +1 do import):
```
if (findContractWfByTypeCode(code)) return `/system/approval-workflows-v2/${code}`
```
`code` = phần sau `AwV2_` (vd `HdTP`, `HdNTNCC`), GIỮ NGUYÊN casing — không đụng chuỗi.

**Việc 3 — comment Pattern 16-bis** (`Layout.tsx:190-194`, 5 dòng, khuôn khối KhkkN `:182-188` cũ): nêu họ `AwV2_Hd*` 7 leaf seed @S188 Order 11..17 · "chỗ thứ 4" Pattern 16-bis · thiếu nhánh ⇒ MenuLeaf DROP IM LẶNG (gotcha #50) · tra bằng BẢNG (nhà mã `lib/contractWorkflowFamily.ts` mirror BE `ContractApprovalWorkflowFamily.cs`), KHÔNG regex đoán ngược (`HdNTNCC` → `NT-NCC` hay `N-TNCC`).

**Việc 4 — 4 thứ CẤM: KHÔNG đụng** (xác nhận bằng diff 1-file):
- nhánh `code === 'Contract'` (`:178` cũ → `:179` nay) — nguyên trạng, không xoá "tiện tay";
- `DbInitializer` — 0 file BE trong diff;
- họ `Khkk_*` — 0 thay đổi (staticMap `Khkk_WfView:40` nguyên trạng);
- không thêm/sửa file nào khác (C-5 union = đúng 1 file).

## Ô acceptance (kết quả từng ô)

| Ô | Lệnh/nguồn | Số đo THẬT | Verdict |
|---|---|---|---|
| **C-13 RANGE** | style-gate `:101-103` | `open=177` · `khkk=189` · `hit=195` · `close=196` · `import=1` | **PASS** — `177 < 195 < 196` ✔ và `195 > 189` ✔ (mốc baseline 176/188/189 dịch +1 do dòng import, quan hệ thứ tự giữ nguyên) |
| **C-2 build** | `npm run build` fe-admin | `✓ built in 20.33s`, **BUILD_EXIT=0**, `dist/assets/index-DUBars48.js 1,776.57 kB` | **PASS** (2 warning chunk>500kB + INEFFECTIVE_DYNAMIC_IMPORT = pre-existing, không phải lỗi) |
| **C-1a eslint** | `npx eslint .` fe-admin, exit qua `${PIPESTATUS[0]}` | sau sửa **42 problems (37 errors, 5 warnings)** — baseline trước sửa **42 (37E/5W)** ⇒ **delta = 0** | **PASS** (≤42, KHÔNG TĂNG; exit 1 = baseline-đỏ-sẵn, không phải hồi quy) |
| C-1a file-wave | `npx eslint src/components/Layout.tsx` | **2 errors** — `290:10` + `364:8`, ruleId **`react-hooks/static-components`** (cả 2 CÁCH XA vùng sửa `:9` / `:190-195`) | **PASS** — ≤4E, **0 ruleId mới** (tổng app không đổi ⇒ không đẻ lỗi ở đâu) |
| **C-5 file list** | `{ git diff --name-only HEAD; git ls-files -o --exclude-standard; } \| sort -u \| grep -E '^fe-'` | `fe-admin/src/components/Layout.tsx` — **đúng 1 dòng** | **PASS** — 0 file lạ (Đ-4 sạch) |
| spec ✅W4(i) 17 leaf sidebar | cần dev-server + BE seed | — | **DEFERRED-TO-LOCAL-VERIFY** |
| spec ✅W4(ii) click "QT Duyệt HĐ — Thầu phụ" → Designer khoá `HD-TP` | cần dev-server | — | **DEFERRED-TO-LOCAL-VERIFY** |
| spec ✅W4(iii) control-âm `KhkkN1` + `DuyetNcc` | cần dev-server | — | **DEFERRED-TO-LOCAL-VERIFY** |

**Ô máy: 4/4 PASS** (C-13 · C-2 · C-1a app + file-wave · C-5). Ô hành-vi: 0/3 đo — DEFERRED (xem dưới).

## DEFERRED/DỪNG (nếu có)

- **DEFERRED-TO-LOCAL-VERIFY — 3 ô hành-vi W4 (i)(ii)(iii)** (spec §③ `:98-100`): worker KHÔNG tự dựng dev-server (tránh chiếm port, theo lệnh giao). Lead đo ở nấc ④ (`npm run dev` fe-admin + BE LocalDB seed 7 `HD-*`). Đây là đường thoát HỢP LỆ theo Đ-7/spec §④.4, **CẤM tick** cho tới khi đo thật.
  - Cần đo: (i) nhánh "Quy trình duyệt (Mới)" đủ **17 leaf** = 2 NCC + 8 KHKK + 7 "QT Duyệt HĐ — …" Order 11..17; (ii) leaf "QT Duyệt HĐ — Thầu phụ" → `/system/approval-workflows-v2/HdTP`, panel khoá mã `HD-TP`, history CHỈ HD-TP; (iii) control-âm: `KhkkN1` + `DuyetNcc` vẫn mở đúng trang cũ.
- **Đ-1..Đ-10: 0 điều kiện dừng kích hoạt.** (Đ-5 neo khớp tuyệt đối · Đ-1 eslint delta 0 · Đ-4 diff đúng 1 file · Đ-10 build xanh.)
- **DEPLOY CHỜ** — dừng ở local-verify + commit, KHÔNG push (theo lệnh giao + plan `:35`).

## Commit

`1cc16a2d` — `[CLAUDE] FE-Admin: YC-029 W4 — sidebar Designer 7 leaf QT Duyệt HĐ (resolvePath AwV2_Hd*)`
(subject ĐÚNG DoD từng ký tự; + trailer `Co-Authored-By` theo nếp repo — 18/30 commit gần nhất có).
`1 file changed, 7 insertions(+)` — `git add` đích danh `fe-admin/src/components/Layout.tsx`. Staged set đo `git diff --cached --name-only` = **đúng 1 dòng**; 8 file dirty khác (`.claude/WAL.md`, `docs/HANDOFF.md`, spec/plan trong run-folder…) là của em main, **KHÔNG stage**. **KHÔNG push** (deploy CHỜ).
