Files
solution-erp/.claude/workflows/runs/2026-07-29-S161-khkk-w1-schema/sub-implementer-frontend-1.md
2026-07-29 19:17:10 +07:00

7.7 KiB

sub-implementer-frontend-1 — W1 §②-10 Designer type-10 KHKK (fe-admin only)

Verdict: DONE — 1 file sửa, npm run build fe-admin PASS 0 TS error. Scope thi công: CHỈ fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx. KHÔNG đụng fe-user (không tồn tại bản sao — fe-user/src/pages/system/ không có thư mục), KHÔNG đụng src/Backend/**, KHÔNG commit.


1. Khảo sát trước khi sửa (grep cùng-lớp mọi chỗ liệt kê ApplicableType)

Trong file Designer — đúng 2 chỗ liệt kê tay, không có chỗ thứ 3:

Chỗ Trước Vai trò
TYPE_CODE_TO_INT (site THỰC :144-148 bản cũ, không phải comment :143) DuyetNcc:1, DuyetNccPhuongAn:2, Contract:3 map :typeCode URL → int, dùng ở :257 selectedTypeInt
DEFAULT_CODE_BY_TYPE (:149-153 bản cũ) 1/2/3QT-DN-V2-001 / QT-DN-PA-V2-001 / QT-HD-V2-001 prefill ô "Mã quy trình", fallback 'QT-V2-001' (:614 bản cũ)

Không có "option list" / bảng nhãn trong FE — trái với giả định của đề bài. Danh sách loại quy trình + nhãn tiếng Việt đến TỪ BACKEND qua GET /approval-workflows-v2TypeSummaryDto.applicableTypeLabel (khai type ở :92-97, render card :294-296, tiêu đề trang :278, tiêu đề dialog :833). ⇒ FE không phải chép chuỗi 'Kế hoạch ký kết HĐ'; nhãn hiển thị đúng hay không là do BE map (ApprovalWorkflowV2AdminFeatures.cs — lane implementer-backend).

Khuôn "entry type=9 TravelRequest" mà đề bài bảo mirror: KHÔNG TỒN TẠI trong file này. TYPE_CODE_TO_INT dừng ở 3 — các loại Office 4..9 (ProposalGeneral…TravelRequest) chưa bao giờ có deep-link riêng ở Designer; chúng vào Designer qua trang tổng (không :typeCode) hoặc module page (WorkflowAppDetailPage.tsx:216 truyền config?.applicableType). ⇒ Khuôn thật để mirror là entry Contract: 3 (loại có deep-link nhưng không có menu leaf). Đã mirror theo đó.

Repo-wide (fe-admin) không có bảng nhãn ApplicableType nào khác — grep Record<number,string> toàn src/: toàn label map của enum KHÁC (ContractPhase, PeType, WorkflowAppStatus, Employee…). Layout.tsx:18 TYPE_CODE_TO_INT là enum ContractType (Ct_/Wf_), không phải ApplicableType.

2. Thay đổi đã land (file:line SAU khi sửa)

  1. :147 const TYPE_INT_CONTRACT_SIGNING_PLAN = 10 — đặt tên cho số 10 vì nó dùng ở 3 nơi (map, default-code, rào checkbox); số trần rải nhiều chỗ là kiểu sửa-1-quên-1.
  2. :151-152 KHKK_EARLY_FINALIZE_NOTE — 1 chuỗi dùng chung cho tooltip 2 ô + dòng ghi chú (không chép 3 lần rồi lệch chữ).
  3. :162 ContractSigningPlan: TYPE_INT_CONTRACT_SIGNING_PLAN trong TYPE_CODE_TO_INT → mở deep-link /system/approval-workflows-v2/ContractSigningPlan (route đã có sẵn App.tsx:76, không cần route mới).
  4. :170 [TYPE_INT_CONTRACT_SIGNING_PLAN]: 'QT-KHKK-V2-001' trong DEFAULT_CODE_BY_TYPE🔴 suy diễn của tôi theo khuôn 3 dòng trên, spec KHÔNG chốt chuỗi này. Chỉ là giá trị GỢI Ý điền sẵn ô "Mã quy trình *" (admin sửa được trước khi Lưu); bỏ dòng này thì rơi về 'QT-V2-001'. Lead/reviewer muốn chuỗi khác thì sửa đúng 1 dòng.
  5. :247 levelFlagsPayload(e, lockEarlyFinalize: boolean) — 2 cờ allowApproverSkipToFinal / allowApproverFinalize ép false khi khoá (:254-255). 2 call-site cùng truyền cờ: PUT :783, POST :815.
  6. :638 const earlyFinalizeLocked = applicableType === TYPE_INT_CONTRACT_SIGNING_PLAN trong Designer (prop applicableType có sẵn :589/:596, TypePanel truyền :417).
  7. :1284-1288 dòng ghi chú xám col-span-2 (chỉ hiện khi khoá) + :1291-1310 ô "Cho phép duyệt thẳng Cấp cuối khi đang duyệt" và :1313-1330 ô "Duyệt là KẾT THÚC quy trình (không trình tiếp CEO)": disabled={earlyFinalizeLocked} (:1306 / :1325), checked={earlyFinalizeLocked ? false : entry.…}, title={… ? KHKK_EARLY_FINALIZE_NOTE : undefined}, className ternary chuỗi class ĐẦY ĐỦ 2 nhánh (Pattern 14 Tailwind JIT — không nội suy mảnh class).

Anchor Edit (bài S133): className col-span-2 flex items-center gap-1 text-[11px] text-slate-700 xuất hiện 6 lần trong khối 9 ô tick ⇒ old_string bao trọn từ comment {/* Mig 31 (S23 t1) … */} tới hết <span>Duyệt là KẾT THÚC…</span> (2 câu chữ hiển thị là phần độc nhất). Không dùng className làm neo.

3. Vì sao khoá ở HAI lớp (render + payload), không chỉ ẩn ô tick

Chỉ disabled ô tick = containment giả: giá trị true vẫn có thể lọt vào state qua copyFromDefinition() (:165-193) rồi đi thẳng lên BE trong payload. Ép false ngay trong levelFlagsPayload là điểm duy nhất mọi đường ghi đi qua (comment :232-240 của chính file khẳng định POST+PUT dùng chung đúng 1 hàm).

Rủi ro 409 đã cân: PUT sửa-tại-chỗ ECHO 2 cờ này và BE so BẰNG (ApprovalWorkflowV2AdminFeatures.cs:580-585) ⇒ ép false sẽ nổ 409 NẾU DB đang giữ true. Với type 10 điều đó không xảy ra: mọi bản type-10 đều do chính màn này tạo (POST đã ép false), và cloneFrom luôn cùng-type (TypePanel truyền type.applicableType :417) ⇒ display và payload luôn khớp, không có màn-hình-nói-một-đằng. Ghi rõ trong comment :242-246.

4. Cờ đỏ / việc KHÔNG thuộc lane này

  • 🔴 Chưa có đường vào bằng sidebar cho type 10. Trang tổng (:291-311) render card mỗi loại nhưng card là <div> không link. Điều hướng per-type đi qua menu leaf AwV2_<Code>Layout.tsx:162-168 allowlist resolvePath (chỗ thứ 4 của Pattern 16-bis, gotcha #50). Hiện MenuKeys.cs:74-75 chỉ có AwV2_DuyetNcc + AwV2_DuyetNccPhuongAnkhông có cả AwV2_Contract, tức type 3 xưa nay cũng chỉ vào được bằng gõ URL. W1 chốt "menu KHÔNG đổi (142 giữ)" ⇒ đúng spec, admin vào bằng URL trực tiếp /system/approval-workflows-v2/ContractSigningPlan. Nếu về sau BE seed leaf AwV2_ContractSigningPlan thì BẮT BUỘC nới Layout.tsx:165 cùng lượt, không thì MenuLeaf trả null → rơi khỏi sidebar im lặng. Tôi KHÔNG sửa Layout.tsx (ngoài scope task).
  • Acceptance §B "Admin tạo được quy trình type=10 3 Bước" chỉ chạy được sau khi BE: (a) ApprovalWorkflowApplicableType.ContractSigningPlan = 10, (b) overview trả type 10 kèm nhãn 'Kế hoạch ký kết HĐ', (c) 3 site liệt-kê-tay trong ApprovalWorkflowV2AdminFeatures.cs (:911/:929, :971/:992, :1044/:1056). Lane implementer-backend.
  • KHÔNG viết test (đợt-2 test-specialist). KHÔNG commit/push.

5. Bằng chứng build

cd fe-admin && npm run build   →   tsc -b && vite build
✓ 1952 modules transformed. ✓ built in 17.39s
dist/assets/index-iNZq9job.js  1,645.50 kB │ gzip: 411.12 kB
dist/assets/index-B5heFn8x.css    84.18 kB │ gzip:  14.04 kB

0 TS error. 3 warning đều PRE-EXISTING: @import Google Fonts phải đứng trước rule khác · chunk >500 kB · realtime.ts vừa dynamic vừa static import.

git status --porcelain phần của tôi: đúng 1 dòng M fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx (git diff --numstat = 67 thêm / 9 xoá). 2 mục còn lại trong cây KHÔNG phải của tôi: .claude/governance/.session-counter.json (harness) và ?? src/Backend/SolutionErp.Domain/ContractSigningPlans/ (lane implementer-backend chạy song song).