K2-TEST: IN-PROGRESS — chưa đo suite (baseline nhận 598/0, CHƯA tự đo)

# sub-test-k2 — K2 TEST lane (S164, wave 2/8, SP-002)

> Luật đan-xen (bài K1/K2-BE): làm mục nào GHI NGAY mục đó, KHÔNG dựng dàn-bài kèm số chưa đo (bài S161-W7d2:
> dàn-bài có sẵn con-số = bẫy claim-trước-đo). Mục chưa chạy CHỈ được tiêu-đề + "CHƯA ĐO".

## §0 Tiền đề — git status TRƯỚC mọi Write

- `git status --porcelain` @start: `sub-test-specialist-1.md` **KHÔNG tồn tại** trong run-folder ⇒ Write mới AN TOÀN.
- File test đang M (lead vừa sửa, CẤM đè): `tests/.../Application/ContractSigningPlanApprovalTests.cs`,
  `tests/.../Common/ContractSigningPlanSchemaTests.cs`.
- Prod code đang M (lane BE K2, CẤM đụng): Features/WorkflowService/entity/config/controller + Mig 71 (untracked).
- Baseline nhận từ lead: 598/0 (45D+553I). CHƯA tự đo (sẽ đo cuối, không tin số đề bài — bài S161-W2).

## §1 Đọc nền — ĐO ĐƯỢC GÌ (đã đọc, trước mọi Write)

Đọc trọn: `sub-implbe-k2.md` (§a-§h) · `sub-invest-fable-b2-cum1.md:77-172` (K2.a-K2.h, blueprint 7 test) ·
`spec-cum1-chi-tiet-31-07-2026.md` (12 vá + checklist ③). Đo lại trên ĐĨA (không tin sổ):

| Thứ cần đo | Site thật | Ghi chú |
|---|---|---|
| submit-guard null | `ContractSigningPlanWorkflowService.cs:174-176` | vá-5 CHẶN null (THẮNG nền `:126` cho-qua) |
| submit-guard khác-nhóm | `…Service.cs:177-182` | message `…cùng nhóm N{plan.ApprovalGroup}` |
| rào (PeId,Group) | `ContractSigningPlanFeatures.cs:393-402` | `Phase != TuChoi` + `ApprovalGroup == approvalGroup` |
| list filter group | `Features.cs:737-738` | ĐẶT SAU khối IDOR `:720-729` |
| Σ Approved | `Features.cs:803-804` | `Sum(l.ApprovedAmount) ?? 0m`, DTO slot 25 `:64` |
| EnsureDraftEditable | `Features.cs:229-237` | owner∥Admin TRƯỚC, phase {DangSoanThao,TraLai} SAU |
| default ApprovalGroup | `ContractSigningPlan.cs:39` `= 1` | mig `:52` defaultValue 0 + `Sql UPDATE … = 1` `:61` |
| site gán-qua-BIẾN | `…Service.cs:327-359` `ReturnOrRejectAsync` | vá-2 chọn phương án (ii) = TEST KHOÁ, cấm sửa code |

**Hạ tầng tái dùng:** `InternalsVisibleTo` CÓ SẴN (`SolutionErp.Application.csproj:25`) ⇒ gọi THẲNG
`ContractSigningPlanScope.EnsureDraftEditable` (Pattern 12, không cần reflection). Global using Xunit +
FluentAssertions (`…Tests.csproj:31-32`). `.slnx` chỉ liệt PROJECT ⇒ file .cs mới KHÔNG cần sửa slnx.

**QUYẾT: file MỚI** `Application/ContractSigningPlanGroupAndCatalogTests.cs` + fixture RIÊNG
(mirror `ContractSigningPlanCrudTests.cs:49-82`, có `AuditingInterceptor`) — KHÔNG chạm 2 file lead vừa vá
(`ContractSigningPlanApprovalTests.cs` fixture SeedPlanAsync +catalog · `ContractSigningPlanSchemaTests.cs`
unique-3-cột), KHÔNG chạm `ContractSigningPlanCrudTests.cs` (helper `CreateAsync` ở đó không mang tham số
nhóm; thêm tham số = sửa file người khác đang dùng).

## §2 Test đã viết — CHƯA ĐO (đang viết)

