diff --git a/.claude/WAL.md b/.claude/WAL.md index 44528ed..84b4c19 100644 --- a/.claude/WAL.md +++ b/.claude/WAL.md @@ -24,8 +24,12 @@ chain: build ×2 PASS — lead RE-BUILD trọng-tài #68 lần-3: diagnostics IDE = stale, build thật XANH; lane khai 2 khoảng-hở UX [3 filter BE chưa UI · tab hiện cả fe-user] chờ lead/anh, KHÔNG tự quyết — đúng luật). Bonus finding: `columns` KIND_CONFIG = config CHẾT từ S29, kind-5 là lần đầu được nối render -[!] wf: B4 K1-test p2 wf_1fb9f309-a27 (relaunch — p1 chết sau đọc-contract): viết ContractCatalogTests 6-test - + chạy suite kỳ vọng 596. 🔴 KHÔNG commit — sau đó: reviewer-gate K1 → chờ OG-6 → commit-push K1 +[x] wf: B4 K1-test ✅ wf_1fb9f309-a27 — 7 test (T1b thêm chống-hồi-sinh #75) · SUITE 597/0 (45D+552I, +7) · + probe VI-PHÂN chứng răng · flaky-DocxOOM tự-khỏi-có-chẩn-đoán · 🔴 lane BẮT tiền-đề lead SAI: p1 ĐÃ + viết file 25KB (mtime>sub-md) — git-status-trước-Write cứu 7 test khỏi bị đè. File Application/ (khai lý). + K1 = BE+FE+TEST TRỌN, UNCOMMITTED. +[ ] NEXT: reviewer-gate K1 (diff ~10 file BE + 6 FE + 1 test vs spec-cum1) → chờ OG-6 anh soát → commit-push + K1 (scope đúng: [CLAUDE] App+Infra+Api+FE-Admin+FE-User+Tests) → K2 (Mig 71 6-item + rào + freeze-răng) [ ] B4 tiếp: K1-FE (×2 app KIND_CONFIG) + K1-test → K2 → K3 → K4a... theo build-order; mỗi wave lead verify + reviewer-gate trước commit; PUSH K1 chờ anh soát OG-6 (bảng transcribe + 8 nhãn) [ ] K8 dry-run: gói test SOLUTION-PE-{n} + B0-form 14 người thật (fail-closed) + đo freeze 2-nhánh diff --git a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-test-k1.md b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-test-k1.md index 01d4361..996f95b 100644 --- a/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-test-k1.md +++ b/.claude/workflows/runs/2026-07-31-S164-4gd-khkk-fanout/sub-test-k1.md @@ -27,6 +27,78 @@ Sẽ đo lại RIÊNG test đó ở §3 để phân biệt flake ⟂ vỡ thật ## PHẦN 2 (relaunch) -### §2 Viết file test — ĐANG LÀM -Relaunch 14:5x. Lượt 1 chết sau §1 (contract đã note đủ → KHÔNG đọc lại code trừ khuôn fixture). -Kế hoạch: `tests/SolutionErp.Infrastructure.Tests/Services/ContractCatalogTests.cs` — 6 test T1..T6. +### §2 Tiền-đề đề bài SAI — file ĐÃ LAND trên đĩa (đo, không suy) +Đề bài relaunch nói "lượt trước chết sau khi đọc contract, **CHƯA viết test**". ĐĨA nói khác: +``` +?? tests/SolutionErp.Infrastructure.Tests/Application/ContractCatalogTests.cs (git status: untracked) +-rw-r--r-- 25005 Jul 31 14:49 ContractCatalogTests.cs # sub-test-k1.md sửa lần cuối 14:46 +``` +⇒ lượt-1 VIẾT XONG file lúc 14:49 rồi chết **trước khi** cập nhật sub-md/return (đúng hình #53: +việc land, vết mất). Sub-md dừng ở "(ĐANG LÀM)" nên lead đọc thành "chưa làm". +🔴 Bài: `git status` 1 lệnh phân biệt "chưa-làm" ⟂ "làm-rồi-mất-vết" — **KHÔNG viết đè**, sẽ mất 7 test. + +Khác 2 điểm so với lệnh (lượt-1 tự chốt, ghi rõ ở header file `:41-42` + `:29-39`): +- Đường dẫn `Application/` (không `Services/`) — `Services/` là chỗ code-generator + workflow-service; + hàng xóm đúng nghĩa = `MasterCatalogFilteredUniqueTests.cs` / `*SeedTests.cs` ở `Application/`. +- **7 test** (không 6): tách thêm **T1b** `Seed_AfterSoftDeleteOfOneCode_DoesNotResurrectIt` — + phép đo riêng cho `IgnoreQueryFilters()` @`DbInitializer.cs:3294` (né #75/#76). + +### §3 Việc CÒN LẠI của lượt này = CHẠY (file chưa từng được biên dịch/chạy) +Rủi ro thật: file 25KB viết xong mà **chưa build lần nào** ⇒ có thể sai chữ ký API (skeleton nấc-2). +Đo: build + chạy filter `ContractCatalogTests` trước, rồi full-suite. + +**Kết quả filter (build SẠCH ngay lần đầu — không sai chữ ký API nào):** +``` +dotnet test tests/SolutionErp.Infrastructure.Tests/... --filter "FullyQualifiedName~ContractCatalogTests" +Passed! - Failed: 0, Passed: 7, Skipped: 0, Total: 7, Duration: 8 s +``` +7 test (không 6): T1 idempotent-86 · T1b không-hồi-sinh · T2 phân bố · T3 unique-filtered 2-chiều · +T4 validator 1..8 · T5 vòng đời handler + xoá mềm · T6 menu-key/policy/grant. + +### §4 Probe VI-PHÂN — chứng T1b có RĂNG (không đụng production) +File tạm `Application/_TempProbeK1.cs` (đã XOÁ) tái lập ĐÚNG biểu thức dò-tồn-tại của seeder +`DbInitializer.cs:3293-3296` nhưng **bỏ `IgnoreQueryFilters()`**, chạy trên chính DB thật sau khi +xoá mềm `A1-01`: +``` +(A) CÓ IgnoreQueryFilters → 86 mã, CÓ "A1-01" ⇒ seeder skip ⇒ không hồi sinh +(B) BỎ IgnoreQueryFilters → 85 mã, THIẾU "A1-01" ⇒ seeder Add lại ⇒ tổng 87 ⇒ T1b ĐỎ +Passed! - Failed: 0, Passed: 1, Total: 1 +``` +⇒ 2 tập KHÁC NHAU ⇒ T1b **phân biệt được 2 thế giới**, không phải assert rỗng nghĩa. +Zero-risk: không mimic production, gọi seeder THẬT, chỉ đổi 1 toán tử ở phía test. +Dọn dẹp verify 2 chiều: `ls` → No such file · `git status --short tests/` → chỉ còn đúng 1 dòng +`?? ContractCatalogTests.cs` (không sót file tạm). + +### §5 FULL SUITE — đo tươi, 0 FAIL +``` +dotnet test SolutionErp.slnx --nologo --verbosity minimal -p:BuildInParallel=false -maxcpucount:1 +Domain: Failed 0, Passed 45, Total 45 (54 ms) +Infra : Failed 0, Passed 552, Total 552 (59 s) +``` +⇒ **TỔNG 597 test / 0 FAIL** (45 + 552). + +Đối chiếu với §0 baseline đo tươi đầu lượt-1: + +| | Domain | Infra | Tổng | Fail | +|---|---|---|---|---| +| §0 baseline | 45 | 545 | **590** | 1 | +| §5 sau K1 | 45 | 552 | **597** | 0 | +| delta | 0 | **+7** | **+7** | −1 | + +- +7 Infra khớp ĐÚNG 7 `[Fact]` của `ContractCatalogTests.cs` — không test nào bị nuốt/trùng tên. +- 🟢 **1 FAIL của §0 TỰ KHỎI**: `Forms.DocxRendererTests.RenderAsync_UnknownPlaceholder_KeepsLiteralToken_NoCrash` + (OutOfMemoryException @`DocxRendererTests.cs:26`) nay XANH khi máy rảnh ⇒ **xác nhận FLAKE do áp lực + RAM lúc fan-out chạy song song**, KHÔNG phải regression. Nghi ngờ §0 đóng bằng phép đo, không bằng đoán. +- ⚠️ Số đề bài ("590/590 → 596") sai cả 2 vế: baseline có 1 fail, và K1 là 7 test chứ không 6. THẬT = 597/0. + +### §6 Không đụng production — không có bug cần báo +- File duy nhất thêm: `tests/SolutionErp.Infrastructure.Tests/Application/ContractCatalogTests.cs` (untracked). +- `git status --short tests/` cuối lượt: đúng 1 dòng `??` đó. `_TempProbeK1.cs` đã xoá sạch. +- KHÔNG commit (theo lệnh). KHÔNG sửa `src/Backend/**`. +- Đọc code K1 lượt này KHÔNG thấy bug. 2 điểm CỐ Ý đáng ghi (đã khoá thành invariant có răng): + · `DbInitializer.cs:3293-3296` dùng `IgnoreQueryFilters()` — **khác** khuôn `:2970` (Projects) và + ĐÚNG hơn khuôn đó (#75/#76); T1b khoá lại để ai "chuẩn hoá về khuôn cũ" là ĐỎ. + · Dup-check handler (`ContractCatalogFeatures.cs:131,193`) chạy trên **active-set** ⇒ khớp index + filtered `[IsDeleted]=0` ⇒ mã của dòng đã xoá tái dùng được (T3 khoá tầng DB, T5 khoá tầng handler). + +END test-k1 — +7 test · 597 PASS / 0 FAIL