wal: flush 20260801T1054
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
IMPLFE-K4C: IN-PROGRESS
|
||||
IMPLFE-K4C: DONE
|
||||
|
||||
# Lane FE K4c — WfView lọc theo nhóm (S166, 2026-08-01) — chốt cụm-2
|
||||
|
||||
@ -10,5 +10,55 @@ Phạm vi: **fe-user ONLY** — fe-admin không có `WorkflowMatrixViewPage` (le
|
||||
- [ ] Xác nhận fetch toàn bộ hay fetch-theo-param (quyết queryKey có cần trục `group` không)
|
||||
- [ ] Đối chiếu `khkkGroupWorkflowCode(n)` (K4a) với code seed BE thật
|
||||
|
||||
## §1 ĐO ĐĨA (ground truth)
|
||||
(append bên dưới)
|
||||
## §1 ĐO ĐĨA (ground truth) — TRƯỚC khi gõ
|
||||
|
||||
### 1.1 Tên field DTO — ĐỌC, không đoán
|
||||
`types/approvalWorkflowV2.ts:39-52` `AwDefinitionDto` có **`code: string`** (`:41`) — đúng tên đề bài dặn phải kiểm. Trang đang render nó ở `:165` (`{wf.code} v{version}`). ⇒ `wf.code === khkkGroupWorkflowCode(n)` khớp field thật.
|
||||
|
||||
### 1.2 Nguồn dữ liệu ⇒ quyết định queryKey (mục 2 đề bài)
|
||||
`:59-67` `useQuery({ queryKey: ['workflow-matrix', typeInt], … api.get('/approval-workflows-v2', { params: { applicableType: typeInt, isUserSelectable: true } }) })`, rồi `:70-71` `summary?.history ?? []`.
|
||||
⇒ Trang **tải TRỌN bộ quy trình của type**, nhóm chỉ là **lát cắt của chính payload đó** ⇒ lọc CLIENT-side, **KHÔNG thêm trục `group` vào queryKey**. Thêm vào sẽ đẻ 8 lần gọi mạng cho cùng một payload + 8 ô cache trùng nội dung. **Khai rõ theo đúng yêu cầu mục 2.**
|
||||
|
||||
### 1.3 Đối chiếu helper K4a ↔ seed BE thật
|
||||
`DbInitializer.cs:609` `var code = $"KHKK-N{n}"` · `:623` **`IsUserSelectable = true`** ⇒ 8 workflow nhóm THỰC SỰ lọt qua bộ lọc `isUserSelectable: true` của trang (nếu seed để `false` thì lọc kiểu gì cũng ra trang trắng — đo trước, không giả định). Helper `khkkGroupWorkflowCode` (types K4a) sinh đúng khuôn đó; cùng chuỗi BE dùng gác phiếu-pin-đúng-nhóm (`ContractSigningPlanFeatures.cs:420` regex `^KHKK-N([1-8])$`).
|
||||
|
||||
### 1.4 `PageHeader` (bản `@/components/PageHeader`)
|
||||
Props = `{ title: ReactNode; description?: ReactNode; actions?: ReactNode }` — **có `actions`** ⇒ đặt đường "Xem tất cả nhóm" ở đó, không phải chế thêm thanh công cụ. (Ghi để khỏi lặp bài S37: repo có ≥2 bản PageHeader khác chữ ký, phải đọc bản đang import.)
|
||||
|
||||
### 1.5 Trang gắn 3 route
|
||||
`/purchase-evaluations/workflow-matrix` · `/contracts/workflow-matrix` · `/khkk/workflow-matrix` (App.tsx `:71/:73/:83`) ⇒ link "xem tất cả" phải bám `useLocation().pathname`, hardcode 1 đường là gãy 2 đường kia.
|
||||
|
||||
## §2 THỰC THI — 1 file, fe-user ONLY (+68 / −5)
|
||||
|
||||
`fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx`:
|
||||
1. `rawGroup = searchParams.get('group')`; `khkkGroup = typeInt === 10 && /^[1-8]$/.test(rawGroup) ? Number : null`. **Chốt chặn kép**: sai type HOẶC group rác ⇒ `null` ⇒ 0 đổi hành vi.
|
||||
2. `allWorkflows` (đổi tên từ `workflows`) → `workflows` = lọc `wf.code === khkkGroupWorkflowCode(khkkGroup)` khi có nhóm. Nhiều VERSION cùng `code` thì giữ đủ (đúng nghĩa "quy trình của nhóm n", không phải "1 bản ghi").
|
||||
3. Header: badge tím `Nhóm N{n}` cạnh tiêu đề + `description` mở đầu bằng `khkkGroupMenuLabel(n)` ⇒ 8 leaf không còn mở ra 8 trang trông hệt nhau.
|
||||
4. `actions`: `<Link to={`${pathname}?type=${typeInt}`}>Xem tất cả nhóm</Link>` — bỏ `group`, giữ đường dẫn đang đứng.
|
||||
5. **Trạng thái rỗng tách 2 nghĩa** (bài "sai-thầm-lặng → thiếu-nhìn-thấy-được"): rỗng-vì-lọc in "…cho nhóm N{n} (loại phiếu này có {N} quy trình ở nhóm khác)"; rỗng-thật giữ nguyên câu cũ. Dùng chung 1 câu thì người dùng nhóm N5 tưởng cả module chưa cấu hình trong khi 7 nhóm kia đang chạy.
|
||||
|
||||
## §3 CHỨNG
|
||||
|
||||
**A. Acceptance 8 URL + các ca bỏ qua** — chạy CHÍNH 2 khối đã ship (`const rawGroup…` và `const workflows =…` cắt từ file bằng `indexOf`) + helper cắt từ `types/khkk.ts` (chỉ bỏ annotation `n: number`, có assert khuôn trước khi thế); dữ liệu thử là 8 code sinh theo **khuôn đọc thẳng `DbInitializer.cs`**. **21/21 OK:**
|
||||
```
|
||||
A ?type=10&group=1..8 → mỗi URL ĐÚNG 1 wf, code KHKK-N1..N8 khớp từng số
|
||||
B ?type=10 trần → hiện CẢ 8
|
||||
group=0 · 9 · abc · rỗng · "03" → KHÔNG lọc (hiện 8) ← "03" là ca dễ lọt nếu dùng Number()
|
||||
type=1|2|3 kèm group=5 → BỎ QUA, 0 đổi hành vi
|
||||
C 2 version cùng code KHKK-N3 → giữ đủ 2
|
||||
D CONTROL-ÂM ① gỡ vị-ngữ lọc (`=== code` → `true`) ⇒ ra 8 wf (phép đo PHÂN BIỆT được)
|
||||
CONTROL-ÂM ② helper sai khuôn (`KHKK_N3`) ⇒ 0 wf, KHÔNG âm thầm khớp
|
||||
```
|
||||
|
||||
**B. Build** — `npx tsc -b` exit 0; `npm run build` fe-user PASS: **1950 modules**, `dist/assets/index-DBtbmn5s.js` 1,643.96 kB (gzip 415.22) · `index-CHYZ6n3Q.css` 92.71 kB · 531ms. Warning >500KB + `INEFFECTIVE_DYNAMIC_IMPORT` = PRE-EXISTING.
|
||||
|
||||
**C. Rào** — `git diff --stat`: **đúng 1 file** `fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx` (68+/5−). `git diff --stat -- fe-admin` = **RỖNG (0-diff)** ✅ đúng lệnh fe-user-ONLY. 0 BE, 0 file khác, **0 commit**.
|
||||
|
||||
## §4 FLAG cho lead
|
||||
|
||||
**FLAG-1 (MINOR — đóng lại FLAG-3 của K4b):** gate-K4b MAJOR-C xử lý xong, `?group=` trên workflow-matrix nay có consumer. Còn lại **1 lệch cố ý đã khai từ K4a**: leaf `Khkk_WfView` của **nhóm 1 phía fe-admin** trỏ Designer (`/system/approval-workflows-v2/ContractSigningPlan`) chứ không phải matrix ⇒ admin không có đường xem-luồng-theo-nhóm. Đúng chủ trương "fe-admin không có `WorkflowMatrixViewPage`" (lead chốt 2026-07-27), nêu lại để cụm-2 đóng sổ mà không ai tưởng là sót.
|
||||
|
||||
**FLAG-2 (MINOR — quan sát, chưa cần làm):** trang lọc theo `code`, nên nếu Admin đổi `Code` của một workflow nhóm trong Designer (ví dụ `KHKK-N5` → `KHKK-N05`) thì leaf nhóm đó ra trang rỗng — **có báo rõ** nhờ câu rỗng-vì-lọc mới, không im lặng. Rào cứng đã nằm ở BE (`Features.cs:420` cũng khớp `^KHKK-N([1-8])$` nên phiếu sẽ không pin được vào workflow đổi mã). Nếu muốn chặt hơn thì khoá sửa `Code` cho 8 workflow nhóm ở Designer — lane admin, không phải lượt này.
|
||||
|
||||
IMPLFE-K4C-END
|
||||
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
# GATE-K4C — IN-PROGRESS
|
||||
|
||||
> Reviewer adversarial gate, wave K4c (chốt cụm-2), S166. Ghi TỪNG MỤC ngay khi đo xong (chống #53: file luôn hợp-lệ giữa chừng).
|
||||
> Verdict CHỈ hợp-lệ khi có dòng `END` cuối file. Chưa có END = lượt chạy chưa xong, ĐỪNG đọc verdict.
|
||||
|
||||
## 0. Bối cảnh nhận từ lead
|
||||
|
||||
- Diff CHƯA commit, lead khai HEAD `ce35f90`, 2 file:
|
||||
- `fe-user/src/pages/pe/WorkflowMatrixViewPage.tsx` (+68/−5) — WfView lọc nhóm client-side
|
||||
- `tests/SolutionErp.Infrastructure.Tests/Application/ContractSigningPlanCrudTests.cs` (+1 Fact) — MAJOR-A `/deleted` lọc server-side
|
||||
- Lane artifacts: `sub-implfe-k4c.md` (DONE, 21/21 + 2 control-âm, 2 FLAG minor) · `sub-test-k4a.md` §MAJOR-A (8/8, RED→GREEN 2 chiều)
|
||||
|
||||
## 1. Đo — điền dần
|
||||
|
||||
(đang đo)
|
||||
@ -1,4 +1,4 @@
|
||||
TEST-K4A: DONE — 7/7 PASS (6 gốc + T7 finding-D) · Infra 569→576 · Domain 45 · tổng 621 · 0 hồi quy · 0 prod-code touched
|
||||
TEST-K4A: DONE — 8/8 PASS (6 gốc + T7 finding-D + 1 gate-K4b MAJOR-A) · Infra 569→577 · Domain 45 · tổng 622 · 0 hồi quy · 0 prod-code touched
|
||||
|
||||
# Lane test K4a — test-after 49 row menu KHKK 8-nhóm (S166, 2026-08-01)
|
||||
|
||||
@ -121,4 +121,37 @@ bộ lọc revoke thì suite vẫn xanh.
|
||||
- **Infra: 576 PASS / 0 FAIL** (baseline 569 + 7) · **Domain: 45 PASS / 0 FAIL**.
|
||||
- **Tổng suite = 621.**
|
||||
|
||||
END sub-test-k4a — VERDICT=7/7 PASS (+7 test, suite 621 = 45 Domain + 576 Infra, 0 hồi quy, 0 prod-code touched)
|
||||
## §MAJOR-A — RESUME 2: nợ gate-K4b, lọc nhóm màn "Đã xoá" (`GET /contract-signing-plans/deleted`)
|
||||
|
||||
- [x] **Chọn file = `ContractSigningPlanCrudTests.cs`** (KHÔNG phải file K4a của tôi): nó có sẵn
|
||||
`KhkkFixture` **có `AuditingInterceptor`** — điều kiện SỐNG CÒN vì màn "Đã xoá" đọc row
|
||||
`IsDeleted=1`; fixture thường xoá CỨNG ⇒ màn rỗng ⇒ test đo nhầm cơ chế (bài S155/S161-W2).
|
||||
Kèm sẵn `SeedPeAsync` + `CreateAsync` + `DeleteAsync`. Dựng lại ở file K4a = nhân bản ~120 LOC.
|
||||
- [x] **+1 Fact `ListDeletedContractSigningPlans_FiltersByApprovalGroup_ServerSide`** (test thứ 8
|
||||
của lớp) + mở rộng helper `CreateAsync` thêm optional `approvalGroup` + helper mới
|
||||
`ListDeletedAsync`. Cùng 1 phiếu PE, 2 nhóm khác nhau (1 và 3) — hợp lệ vì rào "1 PE = 1 kế
|
||||
hoạch sống" khoá theo CẶP (PeId, ApprovalGroup) `:401-404`; workflow seed Code `QT-KHKK-V2`
|
||||
nằm NGOÀI họ `KHKK-N{n}` nên rào (v) `:420-424` cho qua.
|
||||
- [x] 5 vế đo (mỗi vế đều assert **`Total`**, không chỉ `Items` — `Total` = dấu vân tay lọc-SERVER
|
||||
vì `CountAsync` chạy sau mọi `Where`; lọc client-side cho `Items` y hệt mà `Total` = cả thế giới):
|
||||
(1) không-param ⇒ 2/Total 2 · (2) group=1 ⇒ 1/Total 1 đúng phiếu G1 · (3) group=3 ⇒ đúng phiếu
|
||||
G3 (chứng không phải "luôn trả cái đầu") · (4) group=7 ⇒ RỖNG (lọc không khớp ≠ bỏ qua lọc) ·
|
||||
(5) **nhánh ADMIN** ⇒ vẫn lọc đúng (vế lọc nằm NGOÀI khối IDOR `:884-893`; chỉ đo 1 vai thì
|
||||
đẩy vế lọc vào trong `if (!admin)` vẫn xanh). +2 sanity trước phép đo chính (2 row THẬT sự
|
||||
`IsDeleted` ∧ THẬT sự khác nhóm).
|
||||
- [x] **CHỨNG CÓ RĂNG — RED→GREEN 2 CHIỀU, ĐO THẬT, KHÔNG CHẠM PROD:**
|
||||
thế-giới-hỏng ("handler bỏ qua param") **tương đương chính xác** với `Handle(ApprovalGroup: null)`
|
||||
trên MÃ THẬT ⇒ mô phỏng bằng cách tạm đổi ĐÚNG 1 chữ **trong test** (`approvalGroup: 1` → `null`).
|
||||
- 🔴 RED đo được: `Failed: 1` — `Expected g1.Items to contain 1 item(s), but found 2`
|
||||
(đúng chữ ký lỗi mà bản chưa vá sẽ tạo ra: 8 URL `?group=n` trả cùng tập mọi-nhóm).
|
||||
- 🟢 Hoàn nguyên → `Passed: 1`. Verify không dư lượng: `grep "approvalGroup: null)"` chỉ còn
|
||||
2 dòng HỢP LỆ (vế (1) không-lọc và vế (5) admin không-lọc).
|
||||
Cách này chạy trên production code THẬT (mạnh hơn probe mimic của T7) và giữ trọn rào không-đụng-prod.
|
||||
|
||||
## §10 — SỐ CHỐT CUỐI (đo tươi sau MAJOR-A)
|
||||
|
||||
- Filter `~ContractSigningPlanCrudTests`: **8/8 PASS** · filter `~KhkkGroupMenuSeed`: 7/7 PASS.
|
||||
- **Infra: 577 PASS / 0 FAIL** (569 baseline + 7 K4a + 1 MAJOR-A) · **Domain: 45 PASS / 0 FAIL**.
|
||||
- **Tổng suite = 622.** `git status -- src/` sạch phần của tôi (0 prod-code touched).
|
||||
|
||||
END sub-test-k4a — VERDICT=8/8 PASS (+8 test: 7 K4a + 1 gate-K4b MAJOR-A, suite 622 = 45 Domain + 577 Infra, 0 hồi quy, 0 prod-code touched)
|
||||
|
||||
Reference in New Issue
Block a user