Files
solution-erp/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-test-k3.md
2026-07-31 18:03:05 +07:00

111 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

K3-TEST: DONE — suite 614/0 (+5)
# K3-TEST — level-finalize + rào pin-đúng-nhóm (S164)
## §0 Nhật ký (ghi TRONG lúc làm, chống #53)
- [t0] Đọc `ContractSigningPlanApprovalTests.cs` (797 dòng) — fixture `KhkkWorkflowFixture` (SQLite in-mem + AuditingInterceptor),
helper: `AddUserAsync` · `SeedWorkflowAsync(f, code, steps[][][], stepOrderStart, stepOrderStride)` ·
`SeedPlanAsync(f, drafter, wfId, maKeHoach, phase, stepIndex, levelOrder, LineSeed[])` ·
`ActAsync(f, actor, planId, action, comment)``svc.TransitionAsync(planId, action, comment, ct:)` ·
`ReadPlanAsync` · `ReadOpinionsAsync` · `LevelIdOfAsync` · `InboxAsync` · `ShouldBeAt` · `ResultShouldMirror`.
File hiện có 8 [Fact] (2 gate-K2 + T1..T6). git status: file đang `M` (K2 đã sửa) — KHÔNG đè.
- [t0] Baseline đề bài: 609/0 (45D + 564I). SẼ ĐO LẠI TƯƠI (không tin số đề bài — bài S161-W2).
- [t1] Đọc `ContractSigningPlanWorkflowService.cs` — nhánh MỚI `:276-289`:
`if (actingLevel.AllowApproverFinalize && applyLevelFinalize)``EndedByLevelFinalize=true` ·
`ApplyApprovedValuesOnFinalize(plan)` (TRƯỚC gán Phase) · `Phase=DaDuyet` · 2 con-trỏ = null · log · return.
Đứng NGAY SAU `UpsertLevelOpinionAsync` ⇒ ý kiến vẫn ghi. Advance thường ở `:293-318`.
`TransitionAsync(planId, action, comment, bool applyLevelFinalize = true, CancellationToken ct = default)`.
- [t1] Đọc rào (v) `ContractSigningPlanFeatures.cs:409-420`: regex `^KHKK-N([1-8])$` trên `w.Code`,
ĐỨNG SAU `EnsureWorkflowTypeAsync` (:407) và **TRƯỚC** `codeGen.GenerateAsync` (:428)
⇒ 409 ở rào (v) KHÔNG được đốt mã (đo được — khuôn S161-W2 `_AndDoesNotBurnCode`).
- [t1] `ApprovalWorkflowV2AdminFeatures.cs:384-386` — ép-false type-10 ĐÃ GỠ ở **POST tạo version**
(echo `l.AllowApproverSkipToFinal` + `l.AllowApproverFinalize`). PUT sửa-tại-chỗ VẪN chặn
(`:795` không gán, `:813-814` dòng THÊM luôn false) — CỐ Ý theo luật versioning ⇒ KHÔNG test PUT.
Handler `CreateAwDefinitionCommandHandler(IApplicationDbContext db)` — 1 dep ⇒ arrange NHẸ,
làm test HÀNH-VI được (không phải rơi xuống phương án "khẳng định không còn biểu thức").
- [t1] Chỗ đặt test (khai lệch so với đề bài):
* T-a/T-b/T-c/T-e → **append CUỐI** `ContractSigningPlanApprovalTests.cs` (dùng `KhkkWorkflowFixture`).
* T-d → **append CUỐI** `ContractSigningPlanGroupAndCatalogTests.cs`: rào (v) cần
`SeedPeForCreateAsync` (:749) + `CreateAsync` (:814) đã có sẵn ở ĐÓ và là `private`.
Đề bài cho "ApprovalTests hoặc file mới"; chọn file thứ 3 để KHÔNG nhân bản ~70 LOC seed PE.
KHÔNG đè test cũ (chỉ chèn trước dấu `}` cuối class).
- [t2] **BASELINE ĐO TƯƠI (không lấy số đề bài):** `dotnet test SolutionErp.slnx`
Domain **45**/0 + Infra **564**/0 = **609**/0. KHỚP số đề bài.
- [t3] Đã viết 5 test + 6 helper. Build test-project: **succeeded, 0 warning 0 error**.
- [t4] Chạy LỌC 5 test mới (`--filter`): **6 matched, 6 PASS, 0 fail** (6 = 5 của tôi + 1 test
nền `Entity_MacDinhNhomMot_...ConCoKetThucSomMacDinhTat` dính chữ "KetThuc").
`--list-tests` xác nhận ĐỦ 5 TÊN trên đĩa (chống claim-mạnh-hơn-việc-đã-làm):
ApproveV2_CapMangCoKetThuc_ChotPhieuNgay_KhongTrinhTiepBuocSau (T-a)
ApproveV2_CapMangCoKetThuc_NhungBoTick_ThiVanTrinhTiepBuocSau (T-b)
ApproveV2_CapKhongMangCo_ThiKhongBaoGioKetThucSom (T-c)
Create_PinQuyTrinhKhacNhomDuyet_ThiBiChan_VaKhongDotMa (T-d)
CreateAwDefinition_LoaiKhkk_GiuNguyenCoKetThucTaiCap_KhongConEpFalse (T-e)
## §1 Vì sao 5 lưới này KHÔNG rỗng (fault-injection = CẤU TRÚC, không cần sửa mã production)
Ma trận T-a/T-b/T-c dùng **CÙNG MỘT bộ seed** (`SeedFinalizeScenarioAsync`), khác đúng 1 biến:
- cài đặt bỏ qua `AllowApproverFinalize` (không bao giờ finalize) ⇒ **T-a ĐỎ**
- cài đặt bỏ qua tham số `applyLevelFinalize` (cờ một mình quyết) ⇒ **T-b ĐỎ** (phiếu ra DaDuyet
thay vì Bước 3) — tương đương phép "gọi handler THẬT với param=null" của S164-W7d2
- điều kiện viết `||` thay `&&` (mặc định true ⇒ mọi lượt duyệt đều chốt) ⇒ **T-c ĐỎ**
- nhánh finalize quên gọi `ApplyApprovedValuesOnFinalize`**T-a ĐỎ** ở khối chốt giá
- finalize quên vế "chỉ phiếu này" ⇒ **T-a ĐỎ** ở phiếu chứng nhân song sinh
Điều kiện để phép đo có nghĩa (đã assert trong test, không chỉ nói mồm): Cấp mang cờ là
**Bước 2 Cấp 2 / quy trình 3 Bước** ⇒ đường THƯỜNG từ (1,2) đi tới (2,1) **chứ không** tới
DaDuyet ⇒ `DaDuyet` của T-a không thể tới từ đường thường. `StepCountAsync == 3` chốt vế này.
T-d: **cùng một quy trình `KHKK-N5`** cho 2 kết quả trái ngược khi chỉ đổi nhóm phiếu (3 = chặn,
5 = qua) ⇒ rào-chặn-tuốt và rào-chưa-bao-giờ-chạy đều bị bắt. Vế "không đốt mã" có
**control dương**: 001/002/003 tăng thật ⇒ codegen sống, nên "001 ngay sau lần 409" là phép đo
thật chứ không phải hằng số.
T-e: 3 vế — Cấp tick ⇒ true · Cấp không tick ⇒ false (chống "bật bừa") · **đối chứng type-1
`DuyetNcc` cũng true** ⇒ chứng cơ chế là ECHO tham số, phân biệt "đã gỡ ép-false" với
"đổi ép-false thành ép-true".
## §2 KẾT QUẢ ĐO (full suite, chạy SAU khi 5 test land)
```
Domain.Tests Failed: 0, Passed: 45 (không đổi)
Infrastructure.Tests Failed: 0, Passed: 569 (564 + 5)
TỔNG 614 / 0 fail (baseline đo tươi 609 ⇒ Δ = +5)
```
`dotnet build` test-project: 0 warning · 0 error. **0 hồi quy** — 564 test Infra cũ nguyên vẹn.
Phạm vi file đã ghi (`git status`, chỉ 3 dòng, KHÔNG chạm production):
```
M tests/.../Application/ContractSigningPlanApprovalTests.cs +346 1
M tests/.../Application/ContractSigningPlanGroupAndCatalogTests.cs + 81 1
M .claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-test-k3.md
```
(2 dòng `1` = dấu `}` cuối class bị thay khi chèn thêm; không test cũ nào bị sửa/xoá.)
## §3 BUG PRODUCTION: **KHÔNG CÓ** — 5/5 xanh ngay lượt đầu, mã BE đúng như spec K3 mô tả
## §4 QUAN SÁT giao lead (KHÔNG tự sửa, KHÔNG pin thành test)
**(O-1) Ứng viên config-lie #78 còn sót: `AllowApproverSkipToFinal` cho type-10.**
Khối ép-false vừa gỡ ở `ApprovalWorkflowV2AdminFeatures.cs:376-385` bao **CẢ HAI** cờ, nên nay
`:384` echo `AllowApproverSkipToFinal` cho MỌI type kể cả 10. Nhưng
`ContractSigningPlanWorkflowService.cs:47` khai rõ **"`AllowApproverSkipToFinal` giữ nguyên
không port"**, và grep toàn `src/Backend` xác nhận service KHKK **0 lần đọc** cờ này (chỉ PE
`:810` + Contract `:335` đọc). ⇒ Admin tick "Cấp này nhảy thẳng Cấp cuối" trên quy trình KHKK:
DB lưu `true`, máy KHÔNG làm gì — đúng hình config-lie mà chính lane này vừa trả giá để đóng
cho `AllowApproverFinalize`. Lựa chọn: (a) ép false RIÊNG `SkipToFinal` cho type-10, hoặc
(b) ẩn ô tick đó trên Designer khi type=10, hoặc (c) port nốt nhánh. **CỐ Ý KHÔNG viết test
pin `SkipToFinal == true`** — pin nó là biến một khả-năng-lỗi thành "yêu cầu".
**(O-2) Rào (v) neo vào mã CHÍNH XÁC — đã đối chiếu dữ liệu, KHÔNG chỉ đọc regex.**
`^KHKK-N([1-8])$` neo hai đầu ⇒ `QT-KHKK-N5` (có tiền tố) sẽ **lọt rào trong im lặng**.
Đã kiểm nguồn dữ liệu thật: `DbInitializer.cs:609` sinh `var code = $"KHKK-N{n}";` — KHỚP
tuyệt đối ⇒ rào SỐNG trên 8 workflow seed. Rủi ro còn lại thuần đặt-tên: ai tạo tay quy trình
nhóm mà gõ tiền tố sẽ mất rào mà không có tín hiệu nào. (Không đổi mã — chỉ ghi để lead cân
nhắc đưa mã nhóm vào hằng số dùng chung thay vì literal 2 nơi.)
**(O-3) PUT sửa-tại-chỗ CỐ Ý vẫn chặn đổi cờ** (`:795` không gán · `:813-814` dòng thêm luôn
false) — spec vá-3 xếp nhầm vào "cụm ép-false", lead đã khai lệch trong `sub-implbe-k3.md`.
KHÔNG viết test cho PUT theo đúng quyết định đó.