wal: flush 20260801T1045

This commit is contained in:
pqhuy1987
2026-08-01 10:45:31 +07:00
parent ce35f9066b
commit 2023f417d0
4 changed files with 85 additions and 14 deletions

View File

@ -0,0 +1,14 @@
IMPLFE-K4C: IN-PROGRESS
# Lane FE K4c — WfView lọc theo nhóm (S166, 2026-08-01) — chốt cụm-2
Nền: K5 commit `ce35f90`. SPEC PIN: spec-cụm2 vá K4c-10 (phần WfView) + gate-K4b MAJOR-C (FLAG-3 lượt K4b của tôi: `?group=` trên workflow-matrix chưa có consumer).
Phạm vi: **fe-user ONLY** — fe-admin không có `WorkflowMatrixViewPage` (lead chốt 2026-07-27 giữ lệch; K4a đã comment tại `isAdminHidden`).
## §0 Kế hoạch đo trước khi gõ
- [ ] Đọc `WorkflowMatrixViewPage.tsx`: nguồn data, tên field `code` THẬT của DTO workflow, cách đọc `?type=`
- [ ] 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)

View File

@ -1,4 +1,6 @@
GATE-K5: IN-PROGRESS
GATE-K5: PASS — 0 blocker · 6/6 SOI đạt (mất-phiếu + regression GĐ3/4 chứng được là KHÔNG xảy ra) · 1 CLARIFY + 5 MINOR treo · rào commit: `menus.json` untracked ở gốc, đừng `git add -A`
> **Re-đo TRƯỚC verdict** (bài S166 F-1 ②): HEAD trôi `ff4d4dc → 13f7f82 → 80b8cf5` trong lượt review, **toàn `wal: flush`** — `git diff --name-only 13f7f82..HEAD -- src tests fe-admin fe-user` = **0**. Cây code vẫn **đúng 4 file, +466/108**, 2 cặp sha mirror y nguyên, 0 untracked trong vùng code ⇒ verdict đo trên đúng thứ sắp commit.
# Gate K5 — adversarial review cây pipeline GĐ2 mở 8 sub-folder nhóm (S166, 2026-08-01)
@ -47,4 +49,54 @@ Lời khai lane (`tsc -b` ×2 exit 0 + `npm run build` ×2) khớp phần tôi
- Nhánh *"Chưa có dữ liệu ở giai đoạn này."* (`:296`) nay **bị nhánh `groups` chặn trước** ⇒ GĐ2 rỗng hiện 8 ngăn thay vì 1 dòng. Đúng spec "HIỆN ĐỦ 8 kể cả rỗng".
- Không đụng `hideEmpty`: vẫn lọc ở tầng **stage** bằng `stageCount()` = `leaves.length` ⇒ đang tìm-kiếm mà gói không có KHKK thì cả folder GĐ2 ẩn, **không** đổ ra 8 ngăn rỗng.
(đang tiếp tục §6)
## §6 SOI-4 — GĐ3/GĐ4 regression ✅ 0 ĐỔI HÀNH VI (chứng bằng tương đương từng vế)
Nghi-can số-1 là đúng chỗ phải nghi: builder GĐ3/4 **bị viết lại vòng lặp**. Tôi chứng tương đương 4 vế thay vì tin "cùng tập, cùng thứ tự":
| vế | CŨ (`seen` + lặp `peItems`) | MỚI (`Set` + lặp id) | kết |
|---|---|---|---|
| tập id | mọi `p.contractId` truthy | `if (p.contractId) add` | **bằng** |
| thứ tự | lần-xuất-hiện-ĐẦU trong `peItems` | `Set` giữ **thứ tự chèn**, chèn khi duyệt `peItems` | **bằng** |
| khử trùng | `seen.has → continue` | `Set` tự khử | **bằng** |
| dòng phụ | `p.tenGoiThau` (p = phiếu ĐẦU mang id đó) | `peItems.find(p => p.contractId === contractId)` = **cũng là phiếu ĐẦU** | **bằng** |
- **`c.type` KHÔNG bị đụng**: vẫn chỉ xuất hiện ở `onOpen` GĐ4 → `/hard-copies?type=${c.type}` (`:322`), khớp `HardCopiesPage.tsx:64-67`. Hành vi 7-loại-HĐ nguyên vẹn.
- **stage4 an toàn theo cấu trúc**: thân `if (linkage.canHardCopy && c?.hasSealedCopy)` chỉ đọc `c`, **0 tham chiếu `p`** — nên việc biến `p` biến mất khỏi scope vòng lặp không thể làm rơi HĐ. (Nếu có tham chiếu thì `tsc` đã đỏ; tôi kiểm cả hai đường.)
- **Union hôm nay đúng 1 nguồn** `pe.contractId` ⇒ tập HĐ **y hệt trước K5****0 ca HĐ đang hiện bị biến mất**. Vế "HĐ 2..N liên-danh vô hình" là **giới hạn dữ liệu có từ trước**, K5 không làm xấu đi.
- ⚪ Ghi chú (không phải lỗi): `peItems.find` nằm trong vòng ⇒ O(n·m); n = số phiếu 1 gói thầu nên vô hại.
- 🟡 **CLARIFY-2 — một dòng checklist đọc được 2 nghĩa:** *"GĐ2 by approvalGroup · GĐ3/4 by c.type"*. Lane đọc là **"kiểm trục, đừng đụng"**; câu hỏi SOI-4 của lead cũng đọc y vậy ("hành vi 7-loại-HĐ … có biến mất ca nào không"). Nghĩa còn lại — *GĐ3/4 cũng mở sub-folder theo 7 loại HĐ* — thì K5 mới làm nửa checklist. **Hai người cùng chọn một nghĩa không chứng minh nghĩa đó đúng ý owner.** Đề nghị ghim cách đọc vào commit message để nó không quay lại thành "sót".
## §7 SOI-5 — Chỗ cắm FLAG-1: 0 field bịa ✅
- `grep` mọi dòng `+` của diff chứa `lines` hoặc `contractIds`: **9 hit, TOÀN BỘ nằm trong `//` comment**. Dòng chạy được duy nhất đọc dữ liệu là `if (p.contractId)` — field **có thật** (`PeListItem:126`).
- Control âm: `grep "lines\|contractIds" fe-user/src/types/purchaseEvaluation.ts` = **0 hit** ⇒ đúng, `lines[]`/`contractIds` **không tồn tại** trên DTO list; nếu ai đó lỡ gõ thành mã chạy thì `tsc` đỏ ngay. Lời khai FLAG-1 của lane **đo lại thấy đúng**.
- Hình dạng "gom TẬP id" (`Set<string>`) là vế wire được thật, không phải hứa suông: thêm nguồn 2 = thêm 1 dòng tại `:290-291`, không phải sửa vòng lặp.
## §8 SOI-6 — SHA-pair ×2, kế thừa, và phép đo prod
- **Mirror:** `sha256` 2 file đổi ×2 app:
`usePipelineStages.ts` = `edff99314e8b75de39b0123bcdad5d98d8081a5bd294e2e05b1ef784094a19ac` (khớp hash lane khai)
`PipelineStageFolders.tsx` = `bed52f39d595c86a24afd27180146871d52e29943731ffb52f7caf23e66de936`
Thêm phép **đối chứng độc lập**: `diff` từng cặp file = **rỗng cả hai** ⇒ identical theo byte, không chỉ theo hash.
- **`INDEX_PAGE_SIZE` = 200 KHÔNG đổi**, `indexTruncated` KHÔNG đổi, dòng cảnh báo *"Chỉ mục tải 200 bản ghi mới nhất…"* vẫn ở chân folder cha (`:301-305`). FLAG-3 (cảnh báo không lặp ở từng ngăn) **đúng như lane khai** — kế thừa, không phải mới.
- 🔵 **Đo prod (tôi tự curl, admin token, `http=200`):** `GET /api/contract-signing-plans?pageSize=200`**`total = 0`**. Bảng KHKK trên prod **rỗng hoàn toàn**.
- ⇒ Phân bố `approvalGroup`**chân-lý-rỗng**: `{}`. Tôi **không** dùng nó để khẳng định hay bác bỏ điều gì về phân bố nhóm — khai thẳng là chưa đo được, không chờ.
- ⇒ Nhưng nó cho **một sự thật dùng được ngay cho UAT**: hôm nay mở cây trên prod, GĐ2 của **mọi** gói thầu sẽ hiện **đúng 8 dòng rỗng chip "SẮP"**, 0 phiếu. Đó là ĐÚNG theo spec — cần nói trước để người UAT không đọc thành "hỏng".
- 🟡 **MINOR-3 — chữ "SẮP" trên ngăn rỗng:** `SoonChip` vốn nghĩa *"tính năng sắp có"*; đặt lên nhóm rỗng nó thành *"nhóm này sắp có"*, trong khi sự thật là *"nhóm này chưa có phiếu"*. Lane bám tiền lệ folder-GĐ nên **nhất quán**, nhưng K5 nhân nó lên **8 lần mỗi gói** và (theo phép đo prod ở trên) **100% ngăn đều rỗng ngày đầu**. Chữ trong thân ngăn đã nói đúng ("Chưa có phiếu ở nhóm này.") nhưng chỉ thấy sau khi bung. Quyết định thuộc owner, không phải lỗi mã.
- 🟡 **MINOR-4 — a11y: `<button>` lồng trong `<summary>`** (`PipelineStageFolders.tsx:141-160`). `<summary>` mang role=button ngầm ⇒ đây là **nội dung tương tác lồng nhau**, trình đọc màn hình có thể không đọc nút bên trong. Đã kiểm tiền lệ tại base `88e7ecf`: cả 3 `<summary>` của `PipelineTreePanel` và cả 3 của `PurchaseEvaluationsListPage` **chỉ chứa `span`/`svg`** ⇒ K5 là **khuôn MỚI**, không có tiền lệ để bám. Bàn phím/chuột vẫn chạy đúng (`preventDefault` + `stopPropagation` chặn nhịp đóng/mở).
- 🟡 **MINOR-5 — bằng chứng mạnh nhất chết theo phiên:** "15/15 OK" của lane chạy bằng script `new Function` dựng tại chỗ, **không commit**. FE **không có hạ tầng test nào** (`fe-user/package.json` chỉ có `dev|build|lint|preview`, không `vitest`/`jest`). Vật canh bất-biến Σ còn lại trong repo là `console.warn` **DEV-only** — bản prod bị loại bỏ khi build. Tức nếu mai ai sửa vòng phân hoạch thành lọc, **không gì đỏ**. Không đòi lane dựng hạ tầng test trong wave này; ghi để đừng ai đọc "15/15" thành "đã có lưới an toàn".
- ⚪ MINOR-6: với GĐ2, `toKhkkLeaf` chạy **2 lần/phiếu** (1 cho `khkkLeaves` đếm, 1 cho ngăn) ⇒ `stage.leaves` thành mảng **chỉ để đếm**, leaf trong đó không bao giờ được vẽ. Vô hại, nhưng là mỡ thừa nếu sau này gói có nhiều phiếu.
## §9 Các cổng còn lại
| Cổng | Kết | Ghi chú |
|---|---|---|
| Cat 1 Wire/claim | **PASS** | 0 `// Mock`, 0 `alert(`, 0 TODO/placeholder trong dòng `+`. Không phải wave BE nên không có verb để curl; đã curl prod để đo dữ liệu (§8). |
| Cat 2 Schema | **N-A** | `git diff --name-only -- src tests` = **0 file**. 0 migration, 0 entity, 0 DTO. |
| Cat 3 Security | **PASS** | Gate GĐ2 vẫn `KHKK_MENU_KEYS = ['KeHoachKyKet']` — đúng key policy của endpoint, KHÔNG OR `Khkk_*` (gotcha **#85**/#82 giữ nguyên). Ngăn nhóm nằm **bên trong** thân GĐ2, mà `locked` chặn trước cả `groups` ⇒ không mở thêm mặt tấn công, không đẻ lệnh gọi API mới. |
| Cat 4 Code quality | **PASS** | `tsc -b` ×2 = 0 (tôi chạy). Mirror byte-identical. Anti-fiddle: đúng 4 file trong phạm vi spec, 0 file lạc. `LeafList` tách ra là **bê nguyên văn** khối JSX cũ (đối chiếu từng dòng khối `-` với thân hàm mới: `ul`/`li key`/`className`/badge/secondary trùng khít) ⇒ tách hàm KHÔNG kèm sửa lén giao diện. |
| Cat 5 Test | **N-A (khai rõ)** | FE không có hạ tầng test — xem MINOR-5. Không có test BE để tăng vì 0 file BE. |
| Cat 6 Writing | **N-A** | Diff là mã + chú thích nội bộ, không phải văn bản hướng ra ngoài. Chuỗi hiển thị mới đều tiếng Việt đủ dấu: *"Chưa có phiếu ở nhóm này."*, *"(chưa phân nhóm)"*, *"Mở danh sách: …"*. |
## §10 VERDICT
**PASS — 0 blocker.** 6/6 mục SOI của lead đều đo được và đều đạt; 2 chỗ tôi nghi nhất (mất phiếu im lặng · regression GĐ3/4) đều **chứng được là không xảy ra**, bằng tương đương từng vế chứ không bằng lời khai. Phần lõi K5 là loại hiếm: bất-biến Σ được bảo đảm bởi **cấu trúc** (một mảng nguồn, một phép phân hoạch, một chỗ đếm), nên nó không phụ thuộc vào ai đó nhớ cộng cho khớp.
**Còn treo (không chặn commit):** MINOR-1 nhãn ngăn lạc đi sai chỗ · CLARIFY-2 cách đọc dòng checklist GĐ3/4 · MINOR-3 chữ "SẮP" · MINOR-4 nút lồng trong summary · MINOR-5 không có lưới test · MINOR-6 mỡ thừa.
**Trước khi commit — 1 việc THAO TÁC:** `menus.json` (44.656 B) đang nằm untracked ở gốc repo; **đừng `git add -A`**, hãy add đúng 4 file code (+ artifact lane/gate nếu muốn).
**Câu nặng nhất:** cây nay hiện đủ 8 nhóm, nhưng prod đang có **0 phiếu KHKK** (`total=0`, tôi tự curl) — nên thứ người UAT nhìn thấy ngày đầu là **8 dòng "SẮP" rỗng ở mọi gói thầu**, đúng spec mà rất dễ bị đọc thành hỏng; cần nói trước.
GATE-K5-END