Files
solution-erp/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/spec-cum1-chi-tiet-31-07-2026.md
2026-07-31 14:20:44 +07:00

6.2 KiB
Raw Blame History

SPEC CỤM-1 FINAL — K1 + K2 + K3 (lead kết tinh sau B2-r, @S164)

① Đề bài

K1 master-data danh mục (86 row) · K2 phiếu mang hạng-mục + nhóm + freeze-răng · K3 8 workflow nhóm + port-finalize + designer. Nguồn NỀN = sub-invest-fable-b2-cum1.md (33KB, 17 test) — 12 VÁ dưới đây THẮNG khi xung đột (từ B2-r 3 lane: sub-reviewer-c1-l{1,2,3}.md — 41 finding, hội tụ cross-lane).

② 12 vá (build ĐỌC CẢ nền LẪN vá)

  1. 🔴 [3-lane hội tụ] Menu key PHẢI VÀO MenuKeys.All — nền khai ContractCatalog + 8 AwV2_KhkkN* "ngoài All" ⇒ 0 permission row ⇒ sidebar chết (loop grant DbInitializer.cs:2058 nguồn = All; khuôn THẬT: 5 leaf catalog hiện hành MenuKeys.cs:168 + 3 leaf AwV2 :182 đều TRONG All). Fix: cả 9 key VÀO All + KHAI drift dạng DELTA per-wave (B3-A1 — cấm neo tuyệt-đối vì thứ tự ship: K1 = +1 key/+4 policy · K3 = +8 key/+32 policy; mỗi commit kèm lệnh đếm lại MenuKeys.All thực tế + cập nhật 2 row STATUS, đừng Goodhart giữ-số-đứng-yên). Acceptance += "login Admin THẤY leaf trong sidebar ×2 app" + 1 test seed-grant.
  2. 🔴 [L1-F5] GỠ phương án (i) tại site :342 — nền đọc NGƯỢC comment (WorkflowService.cs:36-43 mô tả NGUỒN COPY và khẳng định KHKK CỐ Ý không có site gán-qua-BIẾN; :342 nằm trong ReturnOrRejectAsync chỉ nhận TraLai/TuChoi literal — DaDuyet unreachable qua đó). GIỮ phương án (ii): test khóa khẳng định điều đó. Cấm "sửa" :342.
  3. 🔴 [L2-H2] K3 thêm việc (d): sweep cụm ép-falsegrep -rn "AllowApproverFinalize|AllowApproverSkipToFinal" toàn src + fe-*: gỡ đủ CREATE ép-false server-side ApprovalWorkflowV2AdminFeatures.cs:380-381 + PUT Conflict :591-594/:605-610 + FE levelFlagsPayload ApprovalWorkflowsV2Page.tsx:247-258 (earlyFinalizeLocked :638) — không chỉ note :151-152. Test mới: "tạo version qua CreateCommand type-10 GIỮ được cờ".
  4. 🔴 [L2-H3] KhkkCreatePage ×2 app PHẢI SỬA (mâu thuẫn nền: command +ApprovalGroup required nhưng page ghi "KHÔNG-ĐỔI") — body POST thêm approvalGroup + picker nhóm. Acceptance += "tạo phiếu nhóm 2 TỪ UI ×2 app" (curl-only không đủ).
  5. 🔴 [L2-M6/L1-F6] Chốt nhất quán CatalogEntryId: auto-gen line lúc tạo phiếu được mồi null NHƯNG submit-guard CHẶN null (mọi line phải gán hạng mục trước trình) + validator line-mới-qua-API bắt buộc có. DoD "line khác nhóm → 409" phải chạy trên phiếu CÓ line thật (chống PASS-bằng-tập-rỗng).
  6. [L2-M4] Kéo phase-guard line-edit sau DaDuyet từ K4b VỀ K2 — Σ Features.cs:709-711 tính LIVE, soft-delete line làm số phiếu-đã-duyệt trôi; freeze chưa kín nếu guard nằm cụm-2.
  7. [L2-M5/L1-F13] Mig 71 BỔ SUNG item 6 = cột EndedByLevelFinalize (K2.a hiện chỉ 1-5) + tên mig phản ánh (vd AddKhkkApprovalGroupCatalogAndFinalizeRuntime) + khai ghost-window K2→K3 (cột nằm im tới khi K3 land).
  8. [L1-F8] Bảng consumer += Features.cs:712-713 Σ ProposedAmount (nền sót — list có 2 Σ) + quyết: list thêm Σ Approved sau freeze để list/detail không lệch số.
  9. [L1-F7] Chứng NULL-unique vá lại: unique cũ bị DROP trong chính Mig 71 — mắt xích thật chặn 2-line-NULL-cùng-(Plan,Supplier) phải nêu ĐÚNG (submit-guard vá-5 + backfill line cũ gán từ header-group; đừng dựa index đã chết).
  10. [L1-F9/L2-M2] Sửa nhãn IgnoreQueryFilters: số đúng = "0 hit trong DbInitializer.cs" (toàn src/Backend = 29 hit/5 file — claim "duy nhất"/"0-hit" là sai lây từ comment code); đơn thuốc seed :2970 thiếu IgnoreQueryFilters vẫn ĐÚNG.
  11. [L1-e] Roster: acceptance đo DANH TÍNH — K3.e += mục "mở workflow nhóm N, danh sách người duyệt KHỚP bảng đội hình từng người" + xử 2 cặp gần-trùng (truong.le vs tring.le vs truong.nguyen · thanh.lethanh "Lê Thanh Bình" vs binh.le "Lê Văn Bình") bằng đối chiếu dept + chức danh trên bản LIVE, không match tên trần; dept-lookup :185 thêm null-guard.
  12. [L1-F3/F4] Trích dẫn :44-46 ĐỦ + khai supersede: nguyên văn có "chủ dự án phán 'PHÁ VỠ' @S155" — spec PHẢI khai K3 = ĐẢO phán quyết cũ theo lời owner @S164, kèm việc (e): sửa comment :36-43/:44-46 + 2 lệnh tự-kiểm :292-293 dán PR + cập nhật KhkkWorkflowPanel.tsx:8 ×2 app + HANDOFF:77. [OG-9 CHỐT @S164] anh xác nhận TƯỜNG MINH: "đúng, chỗ budget chốt chặn là a Chương… vậy bài toán trần budget xem như đóng" ⇒ đảo "PHÁ VỠ" @S155 hợp lệ — K3 (a)-(e) HẾT CHẶN. Kèm: NĐUQ = human-gate VĨNH VIỄN (không còn wave enforce-máy nào; xóa mọi ý "opt-in sau").

③ Checklist final cụm-1

  • K1: 7 mục nền + "Admin thấy leaf sidebar ×2 app" + test seed-grant + drift DELTA khai cùng commit.
  • K2 (+B3-A6): nút "Tạo thêm cho nhóm khác" (OG-7 UI-hướng-1) CHỦ = K2, site picker/PE-flow ContractSigningPlanFeatures.cs:1201-1202 + PE-detail — acceptance TỪ UI: PE có phiếu → thấy phiếu + nút phụ, bấm → form preset nhóm khác → 201.
  • K3 (+B3-B3 câu-ranh): fe-admin resolvePath nới CHỈ họ AwV2_KhkkN*CẤM nới họ Khkk_* (fe-admin thiếu WorkflowMatrixViewPage; phép-âm: grep route Khkk_ fe-admin = 0).
  • K2: 8 mục nền + submit-guard null-CatalogEntryId (test ÂM trên phiếu có line) + phase-guard line-edit + Σ×3 nhất quán + Mig-71 6 item + 3-file + backfill=1 + UI tạo-phiếu-nhóm-2 ×2 app + bảng 18 consumer (17 nền + :712-713).
  • K3 (SAU OG-9): 6 mục nền + sweep ép-false ≥4 site + test giữ-cờ-qua-CreateCommand + đo danh tính roster + comment/panel/HANDOFF cập nhật + verify LIVE trước seed.
  • Mọi wave: test ≥590+k khai k · cicd PASS · BE-only smoke API (#77 chỉ khi FE-ship).

END spec-cum1-final — nền 17 test + vá: ~5 test mới · 1 OG mới (OG-9) · 2 blocker menu/ép-false đã đóng đường.