Files
solution-erp/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-reviewer-gate-k3.md
2026-07-31 21:47:23 +07:00

12 KiB
Raw Blame History

REVIEWER-GATE-K3: PASS-WITH-FLAGS — 8 finding (3 MAJOR / 5 MINOR, 0 blocker build-test)

Reviewer gate K3 — 8 workflow nhóm + port finalize + designer

Ghi-đĩa TRONG LÚC LÀM (chống #53). Đo từ ĐĨA, HEAD 2967c43, 25 file M / +908 102; 2 untracked chỉ ở .claude/auto-memory/.

§1 Build / test / npm — số NGUYÊN VĂN

Phép Lệnh Kết quả nguyên văn
BE build dotnet build SolutionErp.slnx Build succeeded. · 0 Warning(s) · 0 Error(s)
BE test #1 dotnet test SolutionErp.slnx 🔴 Failed! - Failed: 1, Passed: 568, Skipped: 0, Total: 569 - SolutionErp.Infrastructure.Tests.dll
BE test #2 dotnet test SolutionErp.slnx Passed! - Failed: 0, Passed: 45, Total: 45 - Domain.Tests + Passed! - Failed: 0, Passed: 569, Total: 569 - Infrastructure.Tests614/0
BE test #3 --filter ~ContractSigningPlan Passed! - Failed: 0, Passed: 34, Total: 34
npm fe-admin npm run build ✓ 1961 modules transformed · ✓ built in 19.63s · 0 TS error
npm fe-user npm run build ✓ built in 7.81s · 0 TS error

⇒ 614/0 = 45D+569I khớp claim ở lượt #2/#3; lượt #1 FAIL → F-4.

§2 Code-vs-spec K3 (5 điểm)

  1. Seed 8 wf khớp ROSTER §0DbInitializer.cs:526-688. 3 Steps (Phòng Cung Ứng / P. Kiểm soát Chi phí / Ban Giám đốc), 11 email Distinct khớp từng dòng bảng §0 sub-implbe-k3.md; Cấp 1 OR-4 / OR-4 / OR-1, Cấp 2 tra.bui / chuong.phan; AllowApproverFinalize=true chỉ(CCM, Cấp 2, chuong.phan) đặt PER-ROW; idempotent AnyAsync(w.Code == code); UNGATED demo-seed.
  2. Finalize qua choke-point + 2-lệnh-grep LUẬT — chạy CẢ HAI:
    • Phase = ContractSigningPlanPhase.DaDuyet:280, :322 (+ :336 là dòng doc)
    • ApplyApprovedValuesOnFinalize:279, :321 (+ doc/def/comment) ⇒ cùng khớp: 2 site gán DaDuyet ↔ 2 site gọi helper, helper đứng NGAY TRƯỚC gán ở cả hai.
  3. Rào (v)ContractSigningPlanFeatures.cs:411-420, regex "^KHKK-N([1-8])$" neo 2 đầu, khớp literal seeder $"KHKK-N{n}" n=1..8; so với approvalGroup (:395 = request.ApprovalGroup ?? Default); code ngoài họ → cho qua.
  4. 8 key VÀO All + DELTA (đếm MÁY)MenuKeys.All = 64 (HEAD 2967c43 = 56) ⇒ +8; policies DERIVED = 256 (HEAD 224) ⇒ +32. 8 menu-row DbInitializer.cs:1980-1989 order 3..10 dưới ApprovalWorkflowsV2. mã — khai (F-3).
  5. FE phép-âm Khkk_ = 0-hit + control dươnggit diff -U0 | grep -E "^\+.*Khkk_[A-Za-z]+: *'" = 0; control dương cùng regex trên cả Layout.tsx = 6 hit ⇒ mẫu CÓ RĂNG. Nhánh mới Layout.tsx:181 /^KhkkN[1-8]$/ nằm TRONG awV2Match, đặt SAU whitelist 3 code cũ.

§3 Phán 3 quyết-định lead

  • (i) GIỮ PUT-Conflict (spec vá-3 bảo gỡ) — LEAD ĐÚNG, spec vá-3 LIỆT NHẦM. UpdateAwDefinitionCommandHandler (:515-649) 0 lần tham chiếu typeEnum/ContractSigningPlan; grep 2 token toàn file cho hit ở :97/:125/:126/:331/:341/:349/:387tất cả thuộc list/create, KHÔNG hit nào trong thân PUT. Guard :598-603 (echo cờ) · :612-617 (dòng mới) · :627-632 (bỏ người giữ cờ) là luật versioning CHUNG mọi ApplicableType; gỡ = nới rào cho PE/Contract/Proposal = regression ngoài scope K3. Thêm: gỡ FE-lock (đúng) đã đủ để cờ seed true không đẻ 409 lúc PUT vì payload nay echo giá trị THẬT.
  • (ii) GIỮ ép-false AllowApproverSkipToFinal type-10 (O-1) — LEAD ĐÚNG ở BE, nhưng sweep BẤT ĐỐI XỨNG (F-2). Tự verify: token AllowApproverSkipToFinal trong ContractSigningPlanWorkflowService.cs = 1 hit duy nhất :47, và là COMMENT ⇒ service 0 lần đọc cờ; control dương: cùng token trong PurchaseEvaluationWorkflowService.cs = 3 hit (code thật) ⇒ grep có răng. Echo cờ cho type-10 = đẻ config-lie #78 mới ⇒ giữ ép-false ĐÚNG.
  • (iii) Seed cờ cùng-commit ≠ config-lie #78 — ĐÚNG, nhánh THẬT tồn tại. ContractSigningPlanWorkflowService.cs:276-289: if (actingLevel.AllowApproverFinalize && applyLevelFinalize)EndedByLevelFinalize=trueApplyApprovedValuesOnFinalize(plan)Phase=DaDuyet → xoá 2 con-trỏ → log → return. Cờ seed CÓ máy tiêu thụ trong cùng diff. (nhưng đường ĐI NGƯỢC — bỏ tick để trình CEO — chết ở tầng UI: F-1)

§4 Ranh giới

  • ReturnOrRejectAsync (:354+), ApplyApprovedValuesOnFinalize (:345-349), nhánh advance thường (:293-329): git diff -U0 trên service chỉ 5 hunk = @@-37,10 (comment) · @@-89,0 (thêm param) · @@-124 (truyền param) · @@-245 (chữ ký private) · @@-266,0 +270,21 (khối finalize MỚI) ⇒ 0 dòng nội-dung đổi trong 3 vùng trên.
  • Submit-guard K2 / file K1: không có trong git diff --name-only.
  • 0 migration mới: git diff --name-only | grep -i migration = 0; git status --porcelain -- src tests | grep '^??' = rỗng.
  • Route/menu-row NGOÀI 8 AwV2_KhkkN*: DbInitializer thêm đúng 8 row; Layout thêm đúng 1 nhánh regex họ AwV2_.
  • Rào (v) chỉ ở CREATE — UpdateContractSigningPlanCommandHandler không chạm ApprovalWorkflowId/ApprovalGroup (0 hit trong thân) ⇒ không có lỗ update-lách.

§5 Test lane (mở ruột 2 test)

  • T-a ApproveV2_CapMangCoKetThuc_ChotPhieuNgay_KhongTrinhTiepBuocSau (ContractSigningPlanApprovalTests.cs:944-994): đo hành-vi THẬT qua service. Sanity 3 vế TRƯỚC (ShouldBeAt(ChoDuyet,1,2) · EndedByLevelFinalize=false · StepCountAsync == 3 kèm lý-do "Cấp mang cờ KHÔNG được là cấp cuối — nếu là cấp cuối thì phiếu kết thúc ở CẢ HAI thế giới và test này xanh mà không chứng minh gì" = anti-tautology guard). Đo SAU 5 trục: phase + 2 con-trỏ · cờ runtime · ApprovedAmount 3 dòng gồm ca ??= giữ 300 · opinion signer. Kèm chứng-nhân song sinh WitnessAtFlagLevel bất động (cả cờ lẫn giá).
  • T-e CreateAwDefinition_LoaiKhkk_GiuNguyenCoKetThucTaiCap_KhongConEpFalse (:1079-1104): 3 vế — (i) tick ⇒ true; (ii) không tick ⇒ false (chặn "bật bừa"); (iii) đối-chứng type khác DuyetNcc cũng true ⇒ phân biệt "gỡ ép-false" với "đổi thành ép-true". Đi qua CreateAwDefinitionCommandHandler THẬT.
  • 0 đè test cũ: git diff -- tests/ | grep -c '^-[^-]' = 2, cả 2 là cùng một sửa cơ-học TransitionAsync(..., CancellationToken.None)(..., ct: CancellationToken.None) (named-arg vì thêm param) — không nới assert nào.

§6 FINDING (8)

MAJOR

  • F-1 fe-{user,admin}/src/pages/khkk/KhkkWorkflowPanel.tsx:136-142opt-out applyLevelFinalize KHÔNG có tầng UI ⇒ trạm CEO chết ở 8/8 workflow seed. Body POST là literal đúng 2 field {action, comment}; grep applyLevelFinalize fe-*/src = 0 hit ở KHKK. Controller ContractSigningPlansController.cs:213 ?? true ⇒ mọi lượt Chương bấm "Duyệt" đều finalize. Seeder cắm cờ cho chuong.phancả 8 workflow ⇒ Step 3 «Ban Giám đốc» (truong.nguyen) không đường nào tới. Đối-chứng chứng minh đây KHÔNG phải khuôn PE: fe-*/src/components/pe/PeWorkflowPanel.tsx:63 = useState(false) + :259 LUÔN gửi tường minh ⇒ PE mặc-định KHÔNG kết-thúc-sớm (opt-in tại UI); KHKK mặc-định LUÔN kết-thúc-sớm. Lời owner OG-3/OG-9 ("a Chương sẽ quyết định là cái đó cần CEO ko") không thực thi được từ UI. Kèm: comment KhkkWorkflowPanel.tsx:15-17 khẳng định "không có gì để panel render thêm" — tiền-đề SAI, chính wave này vừa đẻ tham số để người duyệt quyết. Acceptance: thêm ô tick opt-out ở panel (mirror PeWorkflowPanel.tsx:778), HOẶC khai tường minh lên HANDOFF rằng "trình CEO" hiện chỉ làm được bằng admin bỏ cờ ở Designer.
  • F-2 ApprovalWorkflowV2AdminFeatures.cs:387fe-admin/src/pages/system/ApprovalWorkflowsV2Page.tsx:263 + :1300-1310sweep ép-false bất-đối-xứng ⇒ tick bị NUỐT IM LẶNG. FE gỡ khoá cả 2 ô (gồm allowApproverSkipToFinal), BE giữ ép-false SkipToFinal cho type-10. Admin tick "Cho phép duyệt thẳng Cấp cuối" trên quy trình KHKK → CREATE lưu false, UI không báo gì. Đây đúng class mà comment vừa bị xoá đã cảnh báo ("màn hình nói một đằng dữ liệu một nẻo"), chỉ đảo chiều. 0 test phủ (T-e chỉ đo Finalize). Acceptance: giữ disabled riêng ô SkipToFinal cho type-10, HOẶC bỏ ép-false BE + port nhánh.
  • F-3 docs/STATUS.md:6DELTA đo được nhưng chưa khai. Máy: All 56→64 (+8); policies 224→256 (+32); STATUS vẫn ghi "Policies 224 · Menu keys 56". Spec cụm-1 vá-1 bắt "mỗi commit kèm lệnh đếm lại + cập nhật 2 row STATUS". Tái phát y hệt finding ④ của gate K1 cùng phiên.

MINOR / khai-thật

  • F-4 Suite flake 1/3 lượt: dotnet test SolutionErp.slnx lượt #1 Failed: 1, Passed: 568ContractSigningPlanCrudTests.DeleteContractSigningPlan_SoftDeletes_KeepsChangelog_ThenCreateAgainSucceeds chết ở KhkkFixture..ctor() :62 EnsureCreated()CallSiteRuntimeResolver. Fixture có từ W2 ⇒ không phải K3 đẻ, nhưng câu "614/0 tươi" chỉ đúng 2/3 lượt — đừng khai trần.
  • F-5 DbInitializer.cs:665 — seeder idempotent per-Code thuần skip, 0 nhánh UPDATE: roster đổi (người nghỉ / đổi phòng) ⇒ phải UPDATE tay trên prod. Cùng lớp seeder SP-002 ở K1.
  • F-6 DbInitializer.cs:637-640Description khai "Admin có thể chỉnh người/quyền tại chỗ hoặc tạo version mới": nửa sau đúng, nửa đầu sai với cờ finalizeApprovalWorkflowV2AdminFeatures.cs:598-600 chặn đổi cờ, :627-629 chặn bỏ người giữ cờ khi sửa tại chỗ. Chuỗi này hiển thị ra UI admin.
  • F-7 ContractSigningPlan.cs:51 + fe-*/src/types/khkk.ts:260EndedByLevelFinalize được GHI nhưng chưa expose DTO (chính FE type tự khai). Test T-a lý-giải "FE/GĐ3 đọc cột này" — hiện chưa ai đọc; ghost-window đã-khai, không phải bug, nhưng câu biện-minh mạnh hơn sự thật.
  • F-8 ContractSigningPlanWorkflowService.cs:37-42 + :335-337 — 2 lệnh grep tự-kiểm in ra gồm cả chính dòng /// doc (:336, :337) ⇒ người chạy sau đếm 3 vs 5 rồi tưởng lệch. Nên nêu rõ "bỏ dòng /// khi đếm".

§7 Verdict

PASS-WITH-FLAGS — build 0W/0E · suite 614/0 (lượt tươi) · npm ×2 sạch; 5/5 điểm code-vs-spec khớp; 3/3 quyết-định lead ĐÚNG về kỹ-thuật; ranh giới sạch (0 mig, 0 đổi hành-vi vùng cấm, 0 route ngoài họ). 0 blocker kỹ-thuật, nhưng F-1 + F-2 là nợ HÀNH-VI: F-1 làm mất đúng cái quyền quyết mà owner vừa chốt (OG-3/OG-9); F-2 tái tạo class "UI nói một đằng DB một nẻo" ở ô còn lại. F-3 là acceptance chưa đóng. Owner/lead quyết ship-rồi-vá hay vá-trước-ship.

END sub-reviewer-gate-k3 — TOTAL: 8 finding (3 MAJOR / 5 MINOR) · 0 blocker build-test · verdict PASS-WITH-FLAGS