From 5facab2f482d637429e306325fac73ad4d26021b Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Wed, 12 Aug 2026 21:38:52 +0700 Subject: [PATCH] wal: flush 20260812T2138 --- .claude/WAL.md | 17 +++++-- .../sub-wq1-fe.md | 49 +++++++++++++++++-- .../sub-wq3-test.md | 16 ++++++ .../sub-wq3b-fe.md | 7 +++ 4 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 .claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-wq3-test.md create mode 100644 .claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-wq3b-fe.md diff --git a/.claude/WAL.md b/.claude/WAL.md index 9d01fd61..a3ca2f33 100644 --- a/.claude/WAL.md +++ b/.claude/WAL.md @@ -38,11 +38,20 @@ remake) · Q2 Select loại GIỮ · Q3 PORT 3 món (cần Mig 73 EndedByLevelFi nhánh finalize + DTO nở + body nở + panel ×2) · Q4 = XÁC NHẬN W5 hiện trạng (drafter xoá, approver chỉ trả-lại — đóng vế approver-delete VĨNH VIỄN cho HĐ) · Q5 thay QT-HD-V2-001 bằng 7 HD-* (data-op) + duyệt/history y KHKK (gộp Q1/Q3) + van-xả mirror-theo-KHKK. -[!] WQ3-BE wf-? (mig73+service+DTO+body+guard-mirror+test) ∥ WQ1-FE wf-? (layout KHKK-thuần) -[ ] WQ3b-FE panel 3 món ×2 app (sau 2 wave trên) → commit → WQ5a data-op -[ ] DEPLOY: dọn workspace runner (vá-gốc P0) → push gom → CI → cicd-verify + smoke + báo anh +[x] WQ1-FE DONE 8/8 (ContractListPanel MỚI fe-user-only + MyContractsPage KHKK-thuần; + FLAG panel-3-không-nhân-đôi-nút chuyển WQ3b — sắc) · WQ3-BE #53-skeleton-rỗng NHƯNG + ruột ĐỦ trên đĩa (lead đo 6 mảnh: entity+mig73-3-file+service:527-529+body+DTO+guards + -giữ-nguyên-vì-KHKK-cũng-cho-qua :510-513) · build 0-lỗi · test 693/693 0-regression +[x] WQ5a data-op: seeder QT-HD-V2-001 → IsActive=false từ-lúc-sinh (env mới) + UPDATE Dev + 0/0 verified (bền — idempotent-check là existence, né #75). Prod UPDATE cùng câu SQL + @deploy-verify +[!] WQ3-TEST (4 Fact finalize, kỳ vọng 697) ∥ WQ3b-FE (panel 3 món ×2 + tái-vị-trí máy + duyệt về panel-3 mọi host). wf: wf_2989df28-eb6 · artifact sub-wq3-test.md + sub-wq3b-fe.md +[ ] Lead: verify-local vòng 2 (layout mới + finalize) → commit WQ* theo cụm → + DEPLOY: dọn workspace runner → push gom → CI → cicd-verify + prod UPDATE Q5a + + STATUS:476 lật → báo anh kiểm -next: chạy WQ3-BE + WQ1-FE song song. +next: chờ wf_2989df28-eb6 → gate → commit → deploy. verify: commits: git log --oneline -8 # 2ae62f3f ed3b39ff 7b291014 09ebd20e 1cc16a2d + wal diff --git a/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-wq1-fe.md b/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-wq1-fe.md index b4566976..f2cfe3a7 100644 --- a/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-wq1-fe.md +++ b/.claude/workflows/runs/2026-08-12-S190-soltuon-dieu-chinh-hd/sub-wq1-fe.md @@ -1,16 +1,57 @@ # WQ1-FE — remake /my-contracts về layout KHKK-THUẦN (S190 · YC-030 Q1) Vai: implementer-frontend · run `2026-08-12-S190-soltuon-dieu-chinh-hd` -Ranh: Write/Edit CHỈ {fe-user MyContractsPage.tsx · fe-user components/contracts/ContractListPanel.tsx (MỚI) · sub-md}. KHÔNG fe-admin · KHÔNG ContractWorkflowPanel · KHÔNG commit. +Ranh: Write/Edit CHỈ {fe-user `MyContractsPage.tsx` · fe-user `components/contracts/ContractListPanel.tsx` (MỚI) · sub-md}. KHÔNG fe-admin · KHÔNG `ContractWorkflowPanel` · KHÔNG commit. +(File này = sub-MD của lane; alias trong footer spawn là `sub-implementer-frontend-1.md` — nội dung KHÔNG tách đôi, tất cả ở đây.) ## Việc đã làm -- [lượt 1] Ghi khung rỗng file này (chống #53 — append sau MỖI đơn vị việc). +- **[lượt 1]** Ghi khung rỗng file này (chống #53 — append sau MỖI đơn vị việc). +- **[đọc khuôn]** `fe-user/src/pages/khkk/KhkkListPage.tsx` :1-281 trọn · `fe-user/src/components/khkk/KhkkListPanel.tsx` :1-491 trọn · hiện trạng `fe-user/src/pages/contracts/MyContractsPage.tsx` :1-369 (bản sau W2+W3). +- **[đo đĩa trước khi gõ — 4 phép, đổi cả thiết kế]** + 1. `ls fe-admin/src/pages/contracts/` = `ContractCreatePage` · `ContractDetailPage` · `ContractsListPage` · `HardCopiesPage` ⇒ **KHÔNG có `MyContractsPage`** ⇒ component mới là **fe-user-ONLY có chủ đích**, KHÔNG có cặp SHA để mirror (khai ngay ở header file mới :6-11). + 2. 🔴 `fe-user/src/components/contracts/ContractDetailContent.tsx:331-335` **ĐÃ render ``** trong nhánh `isV2` ⇒ nếu panel-3 render thêm thì **một HĐ có HAI bộ nút Duyệt/Trả lại** — đúng thứ chính khối W6 cấm ở `ContractDetailContent.tsx:140-142` ("để cả hai thì cùng một HĐ V2 có 2 đường bấm duyệt"). ⇒ **lệch spec có chủ đích**, xem §DEFERRED. + 3. `usePipelineStages.ts:83` + index `enabled: canPe` ⇒ cây GĐ3 cũng chết khi thiếu quyền Duyệt NCC ⇒ **bê nguyên mitigation M-1 của KHKK** (`!canPe` ép chế-độ phẳng), nếu không thì gộp 2 cột thành 1 sẽ làm người chỉ-có-quyền-HĐ **mất trắng danh sách** (mặt còn lại gotcha #82). + 4. `git show 502f4d2e:…MyContractsPage.tsx` (bản TRƯỚC-W2) ⇒ panel-3 khi đó = `WorkflowHistoryPanel` trong `aside … w 360px p-4` ⇒ **bề ngang 360px đã có tiền lệ chạy thật** (bài học #15: đo bề ngang trước khi port khuôn). +- **[thi công 1]** TẠO `fe-user/src/components/contracts/ContractListPanel.tsx` (346 dòng) — mirror-ADAPT `KhkkListPanel`: + - filter-block trên cùng theo đúng thứ tự spec: `Select` **loại HĐ** (Q2 — giữ từ W2) → ô **Tìm** → `Select` **trạng thái** (khuôn KHKK, nguồn nhãn `ContractPhaseLabel` 12 mục). + - `flatMode = !canPe || term.length > 0 || phase !== null || pendingMe || deletedView` (`:139`). CÂY = mặc định: `PipelineTreePanel currentStage={3} hideHeader hideSearch bodyMaxHClass="lg:max-h-none"` + `stage2Options={{ onOpenContract, stage3TypeFilter }}`. + - Query `['my-contracts', type, phase, deletedView, term, pendingMe]` **dời nguyên từ host xuống panel** + `enabled: flatMode` (khuôn `KhkkListPanel.tsx:260` — chế-độ cây KHÔNG gọi endpoint nữa). Giữ nguyên 3 nhánh endpoint của W3/W7: `deleted` → `pendingMe` (`/contracts/inbox`, 0 tham số, lọc loại ở client, nợ `[carry:w7b-inbox-param]`) → thường. + - Card `ContractRowCard` = **markup cũ dời chỗ, không vẽ lại** (mã · tên · NCC · chip phase · giá + `SlaTimer`). + - **THÊM 3 thứ KHÔNG có ở bản W2** (đều là chống-câm, khai ở đây để reviewer không tưởng scope creep): (a) nhánh `list.isError` + nút "Thử lại" — trước đó lỗi mạng đọc thành "Không có HĐ"; (b) chân cột `x / total HĐ` + cảnh báo cắt `PAGE_SIZE=100` (trang chưa có UI phân trang); (c) dòng chữ hiện "cây dựng từ phiếu Duyệt NCC — HĐ ngoài gói không nằm trên cây…" chỉ hiện ở chế-độ cây. +- **[thi công 2]** VIẾT LẠI `MyContractsPage.tsx` (369 → 215 dòng): grid GIỮ `[400px_1fr_360px]`; panel-1 = `ContractListPanel`; panel-2 = `ContractDetailContent` (bỏ `WorkflowHistoryPanel` khỏi đây); panel-3 = **khuôn KHKK QĐ-2** hộp `border-dashed` + icon `X` khi chưa chọn ⟂ `WorkflowHistoryPanel` khi đã chọn. **BỎ cột danh-sách thường-trực** (nay là chế-độ phẳng của panel-1). BỎ badge `{rows.length}` ở header (không còn nguồn: chế-độ cây không có "số dòng" — số đếm xuống chân panel-1). +- **[thi công 3]** Lớp override lọc: 1 state `{nav, type, phase}` **đóng dấu leaf** (`navKey = type|phase|deleted|pendingMe`) — đổi leaf ⇒ dấu lệch ⇒ override tự rơi. **KHÔNG `useEffect`** (bài W2: ăn `react-hooks/set-state-in-effect`, 47→48) và **KHÔNG set-state-trong-render** (khuôn KHKK `KhkkListPage.tsx:83-88` dùng cách đó; ở đây dẫn-xuất thuần nên tránh luôn rủi ro lint). 3 trạng thái `undefined`/`null`/số giữ nguyên nghĩa KHKK. +- **[thi công 4]** `Select` loại HĐ nay lọc **CẢ cây LẪN danh sách** (W2: chỉ cây). Lý do khai tại `ContractListPanel.tsx` khối `queryFn`: gộp 2 cột thành 1 mà `Select` chỉ lọc cây thì ở chế-độ phẳng nó là **nút chết**. Kéo theo: `typeLabel` ở header + `?type=` của nút "Tạo HĐ mới" đọc loại **ĐÃ GIẢI** (khuôn `KhkkListPage.tsx:151-153` đọc `group` đã giải) — chọn "Tất cả loại HĐ" mà tiêu đề còn treo tên 1 loại là tiêu đề nói dối. +- **[GIỮ nguyên]** `?id=` chọn tại chỗ · deep-link `/contracts/{id}` khi `500 kB + `INEFFECTIVE_DYNAMIC_IMPORT src/lib/realtime.ts`), đúng như 3 đợt trước — không đổ lỗi cho đợt này. + +Pattern 16-bis 4-place: **N/A có bằng chứng** — không thêm route/menu-key nào. `fe-user/src/App.tsx:66` đã có ``; `Layout.tsx:90,166,174,179` đã trỏ 4 leaf về đúng URL này. Đợt này chỉ đổi RUỘT của trang. + +Diện chạm: `git status --short fe-user fe-admin` = **đúng 2 dòng** (`M MyContractsPage.tsx`, `?? ContractListPanel.tsx`), **fe-admin 0 dòng**. ## DEFERRED/DỪNG -(chưa có) +1. 🔴 **FLAG WQ1→WQ3b — panel-3 CỐ Ý KHÔNG có `ContractWorkflowPanel` (lệch spec BƯỚC 2(2), có bằng chứng).** Spec bảo panel-3 = `ContractWorkflowPanel + WorkflowHistoryPanel`, nhưng `ContractDetailContent.tsx:331-335` **đã** render `ContractWorkflowPanel` (nhánh `isV2`) và `ContractDetailContent` chính là panel-2 ⇒ làm đúng chữ spec = **2 bộ nút Duyệt/Trả lại cho cùng 1 HĐ**. Gỡ khối `isV2` khỏi `ContractDetailContent` là cách đúng, nhưng file đó (a) **ngoài ranh WQ1**, (b) là **cặp mirror ×2 app**, (c) còn nuôi cả `ContractDetailPage` fullpage. ⇒ Để WQ3b/lead quyết. Panel-3 hiện = dashed ⟂ `WorkflowHistoryPanel` (sơ đồ quy trình + duyệt phòng ban + lịch sử) = đúng hình KHKK QĐ-2 **trừ 2 nút bấm**. +2. **HÀNH VI = DEFERRED-TO-LOCAL-VERIFY** (lead đo trên máy): (a) cây GĐ3 mở ra đúng ở `/my-contracts` trần; (b) gõ tìm / chọn trạng thái ⇒ nhảy sang danh sách phẳng và ngược lại; (c) 4 leaf menu (List/Pending/Approved/Deleted) vào đúng chế-độ; (d) `