diff --git a/.claude/WAL.md b/.claude/WAL.md index 2e5fbd1c..0290483c 100644 --- a/.claude/WAL.md +++ b/.claude/WAL.md @@ -9,9 +9,9 @@ chain: [x] /tiep S190 trọn (sàn-3 ⑤ cân sổ · verify site+marker+A/059 Phase=10 · tick 64 · se=0/all=0 · ctx-verifier 13 cờ → vá run.md S189 + di-trú 2 carry vào HANDOFF + WAL số mục) [!] B1 /fable-real investigator-codebase — invest 5 điều chỉnh + đối chiếu khuôn KHKK/NCC - → propose wave+checklist. wf: wf_c8b1d8ba-4b0 · 1 lane tier=fable · run-folder - runs/2026-08-12-S190-soltuon-dieu-chinh-hd/ (anh-mo-ta.md + run.md đã scaffold) · - artifact sub-invest-b1-fable.md · đứt thì relaunch-cắt-gọt theo tiep.md §4 + → propose wave+checklist. Lượt-1 wf_c8b1d8ba-4b0 #53-partial (Thứ-1+Thứ-3 XONG trên + đĩa — root-cause bug menu A+B đủ file:line). wf: B1b wf_9094b868-9ea relaunch-cắt-gọt + làm nốt Thứ-2/4/5+Đọc-ý+PROPOSE · artifact sub-invest-b1-fable.md (append cùng file) [ ] B2 /fable-clone reviewer — review spec/wave B1 (≥3 lane opus, đóng-gói C2) [ ] B3 /fable-real ×2 style: front-end-reviewer-style + back-end-reviewer-style → spec-list style đồng nhất khuôn KHKK/DuyetNCC diff --git a/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/run.md b/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/run.md index 13f1532c..56ab39ff 100644 --- a/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/run.md +++ b/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/run.md @@ -29,3 +29,13 @@ HEAD lúc mở run: ae1dcf4a · HMW-mode ON · lead Opus 5 MAX (default) ## Stages *(append theo tiến độ — mới nhất ở cuối)* + +- **B1 lượt-1** `wf_c8b1d8ba-4b0` (30 tool-use · 165K tok · ~8'): return RỖNG (#53 — + "completed without StructuredOutput") nhưng ARTIFACT cứu ~50%: **Thứ-1 layout** (3-panel + my-contracts vs khuôn KHKK 400px cây-trái + gap `stage3Options`/`onOpenContract`) + + **Thứ-3 root-cause A+B ĐỦ** (A: WfView 7 loại cùng `?type=3` [ApplicableType] ⟂ accordion + auto-expand `Layout.tsx:470-485` đọc `type` mù ngữ-nghĩa → mutex đóng/mở nhầm nhóm; B: + `Đã duyệt` dùng `phase=9` transient làm danh tính → 2 leaf cùng sáng — PE đã chữa bằng + `view=approved`, `Ct_*` không bắt chước). Thứ-2/4/5 + Đọc-ý + PROPOSE = pending. +- **B1b relaunch-cắt-gọt** (tiep.md §4 tinh thần): lane fable MỚI làm nốt 5 phần pending, + append CÙNG file `sub-invest-b1-fable.md`; phần đã xong = ground-truth CẤM làm lại. diff --git a/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-invest-b1-fable.md b/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-invest-b1-fable.md index cbb46725..0974c318 100644 --- a/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-invest-b1-fable.md +++ b/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-invest-b1-fable.md @@ -8,7 +8,23 @@ ## Thứ-1 layout cây toàn trình -(pending) +**Hiện trạng my-contracts (fe-user `pages/contracts/MyContractsPage.tsx`):** +- Grid 3-panel `lg:grid-cols-[320px_1fr_360px]` (`:153`). +- Panel-1 TRÁI 320px = **danh-sách HĐ** (search "Tìm theo mã / tên / NCC…" `:162` + empty-state "Không có HĐ — Loại HĐ này chưa có dữ liệu" `:180`) → khớp KHOANH ĐỎ #1 ảnh 1. +- Panel-2 GIỮA = `ContractDetailContent` / placeholder "Chọn 1 HĐ ở danh sách bên trái" (`:219-233`). +- Panel-3 PHẢI 360px = `PipelineTreePanel currentStage={3}` khi chưa chọn (`:242`, quyết định owner S168 slot 63 "trade-off D"), chọn HĐ thì `WorkflowHistoryPanel` (`:243`) → khớp KHOANH ĐỎ #2 "CÂY TOÀN TRÌNH (45 gói)". + +**Khuôn KHKK (`pages/khkk/KhkkListPage.tsx` + `components/khkk/KhkkListPanel.tsx`):** +- Grid `lg:grid-cols-[400px_1fr_360px]` (`KhkkListPage.tsx:171`). +- Panel-1 TRÁI 400px = `KhkkListPanel` = **CÂY TOÀN TRÌNH** (owner QĐ-1 2026-08-04, `KhkkListPanel.tsx:9`) — `PipelineTreePanel currentStage={2} hideHeader hideSearch` (`:382-386`) + **flat-list fallback server-side** khi gõ search / chọn Select trạng-thái / `!canPe` (`flatMode`, mitigation R-11/M-1 `:21-24,366-371`), leaf-mode 4-tầng cho Đang duyệt/Đã duyệt/Đã xóa (`:395-405`). +- Panel-3 PHẢI = workflow + lịch sử; chưa chọn = hộp dashed, owner QĐ-2 **CẤM nhét cây vào panel-3** — comment tự khai "Khác GĐ3 ở điểm này là CÓ CHỦ ĐÍCH" (`KhkkListPage.tsx:252-256`) ⇒ chính chỗ "cố ý khác" này là thứ anh bây giờ bảo ĐỔI về giống KHKK. +- M-2 (`KhkkListPanel.tsx:16-17`): card phiếu trên cây gọi `onSelect` của host (chọn vào panel-2) thay vì navigate rời trang — qua opt-in `stage2Options.onOpenKhkk` (`PipelineTreePanel.tsx:111`, `usePipelineStages.ts:185,244`). + +**Gap kỹ thuật khi dời cây sang trái ở my-contracts:** +1. `PipelineTreePanel` CHƯA có `stage3Options` — leaf HĐ GĐ3 hiện `onOpen: () => navigate('/contracts/${contractId}')` (`usePipelineStages.ts:377`) = bấm 1 phát văng khỏi màn 3-panel (đúng bệnh M-2 đã chữa cho KHKK). Mirror cần thêm opt-in `onOpenContract` (analog `onOpenKhkk` :185/:244) để chọn vào Panel-2 qua `?id=`. +2. Danh-sách HĐ đi đâu: theo khuôn KHKK = **flat-list là chế-độ fallback trong CÙNG panel trái** (search server-side/lọc trạng thái → flatMode), không phải cột riêng. Panel-3 khi chưa chọn = hộp dashed (khuôn QĐ-2), chọn HĐ = `WorkflowHistoryPanel` như cũ. +3. Bề rộng panel trái nên lên 400px như KHKK/PE (KhkkListPage tự khai số đo lấy của PE "giống nhất với Duyệt NCC"). +4. fe-admin có `MyContractsPage` mirror? — cần check cặp SHA (KHKK khai MIRROR SHA256 identical với fe-admin counterpart; ContractsListPage admin là trang khác). ## Thứ-2 per-loại-HĐ @@ -16,7 +32,21 @@ ## Thứ-3 BUG menu nhảy lẫn (root-cause) -(pending) +**ROOT-CAUSE A (chính — tái hiện được, đúng chữ "click menu này NHẢY sang menu khác"): leaf "Luồng duyệt" của CẢ 7 loại HĐ mang `?type=3` ⟂ accordion auto-expand đọc `type` mù ngữ-nghĩa.** +- `fe-user/src/components/Layout.tsx:151`: `Ct__WfView → /contracts/workflow-matrix?type=3&ct=${typeInt}` — comment tự khai "WfView cả 7 loại đều ?type=3 (HĐ chung 1 bộ workflow V2) — thêm &ct=N để active-state riêng từng leaf". Ở URL này `type` = **ApplicableType** (3=Contract), KHÔNG phải ContractType. +- Accordion auto-expand `Layout.tsx:470-485`: useEffect đọc `params.get('type')` cho MỌI pathname ngoài `/purchase-evaluations` (nhánh else `:479-483` nuốt luôn `/contracts/workflow-matrix`) → `INT_TO_TYPE_CODE[3] = 'NhaCungCap'` (`:16-29`) → `setExpandedCtCode('NhaCungCap')`. +- **Chuỗi tái hiện:** đang mở nhóm "01. HĐ Thầu phụ" → click leaf "Luồng duyệt" → URL `?type=3&ct=1` → accordion mutex (1 Ct_ mở tối đa, `:464-467`) ĐÓNG nhóm 01 + MỞ nhóm "03. HĐ Nhà cung cấp". Leaf active thật (WfView ct=1) bị giấu trong nhóm đã đóng; nhóm 03 mở ra không leaf nào sáng (WfView nhóm 03 pin `ct=3` ≠ 1, `queryMatches:368-374` so nghiêm key pinned). Với user = "click menu này nhảy sang menu khác". Đây là ĐÚNG bug-class "2 nghĩa của type" (ApplicableType ⟂ ContractType — trục đã cảnh báo trong project-memory SP-002). +- Cùng lớp: click "Luồng duyệt" nhóm 3 thì KHÔNG nhảy (trùng số 3 tình cờ) — giải thích vì sao bug chập chờn "menu lẫn lộn". + +**ROOT-CAUSE B (phụ — sáng-nhầm-2-mục): leaf "Đã duyệt" = `?type=N&phase=9` (`Layout.tsx:152`) dùng `phase` TRANSIENT làm danh tính — tái phạm đúng bug S155 mà PE đã chữa.** +- `phase` ∈ `TRANSIENT_QUERY_KEYS` (`:350`). `queryMatches:369` chỉ bỏ-qua transient khi ĐÍCH không pin → đứng ở "Đã duyệt" (`?type=1&phase=9`): leaf "Đã duyệt" (pin phase) khớp NGHIÊM ✓ sáng, leaf "Danh sách" (target `?type=1`, không pin phase → phase ignorable) CŨNG khớp ✓ sáng ⇒ **2 leaf cùng sáng 1 lúc**. PE đã chữa đúng ca này bằng khoá định danh `view=approved` (`:180-185` tự khai luật "URL trùng hệt → menu sáng nhầm — bug UAT anh báo 2026-07-27") — `Ct_*_Approved` :152 KHÔNG bắt chước. +- Đối chứng: "Đã xóa" dùng `deleted=1` (không nằm TRANSIENT) = danh tính chuẩn → không dính. + +**Gotcha ứng viên — phán quyết:** #34 (NavLink pathname-only) = KHÔNG PHẢI thủ phạm trực tiếp — fe-user đã có custom `queryMatches` (:354) chính là thuốc của #34; bệnh còn lại là 2 lỗ TRÊN thuốc (A: accordion side-channel không đi qua queryMatches; B: transient-vs-identity). #50 (resolvePath drop im lặng) = không tái ở đây, 42 leaf Ct_* đều resolve. #85 (OR-gate key) = không liên quan điều-hướng. + +**Fix đề xuất (FE-only, 0-mig):** +1. WfView route mang danh tính loại làm trục chính: đổi `:151` thành `/contracts/workflow-matrix?ct=N` (bỏ `type=3` khỏi URL; `WorkflowMatrixViewPage` tự suy applicableType=3 khi ở path `/contracts/workflow-matrix` — nó đã có khuôn alias-path cho khkk `?type=10`), HOẶC tối thiểu: auto-expand `:470-485` ưu tiên `ct` khi có + loại trừ pathname `/contracts/workflow-matrix` khỏi nhánh else. +2. Approved: `:152` thêm khoá định danh `&view=approved` y khuôn PE `:185` (giữ `phase=9` làm bộ lọc thật; trang `MyContractsPage` đã bỏ qua param lạ). ## Thứ-4 bộ thao-tác vs khuôn KHKK