wal: flush 20260729T2300

This commit is contained in:
pqhuy1987
2026-07-29 23:00:12 +07:00
parent 1e3434b32c
commit fe1f6b0ecf
2 changed files with 42 additions and 1 deletions

View File

@ -29,7 +29,8 @@ chain:
- [x] commit W3 `df52fa0` (11 file +2.370/6) PUSHED
- [x] **W3 ĐÓNG — cicd VERDICT=PASS 5/5** (§1 CI 580 + §3 marker [né PASS-GIẢ "Đến lượt bạn duyệt"] = cicd · §2 0-mig/96/142 + §4 smoke transitions THẬT 409-đúng-lời + 404-ProblemDetails + §5 CỜ 13/13/2 = lead 2-nguồn). Synthesis `runs/2026-07-29-S161-khkk-w3-duyet/w3-synthesis.md`. **GĐ2 KHKK trọn vòng đời phiếu trên prod.** Tồn: mark-read chuông cũ (chờ anh) · UAT tay cần WF-type-10 + non-Admin
- [x] gate 5-anchor W6 PASS 5/5 (content-exact 0-drift)
- [!] wf: W6 đợt-1 `wf_e3b6a2bc-91d` ĐANG CHẠY — 1 lane BE {view per-HĐ 3-site :301/:381/:486 · inbox v2-set + nhánh ADMIN DR-4 · guard trình +PMH; CẤM đụng Reject :49-66 O-A + vùng W3 :217-394} — run-folder `runs/2026-07-29-S161-khkk-w6-duongong/`. Sau: đợt-2 test 5-PIN → reviewer (security-wave) → ship
- [x] W6 đợt-1 `wf_e3b6a2bc-91d` XONG (#53, sub-md 3.7KB §0 + code trọn): 3 fix land (+142 ContractFeatures [3-site + inbox v2 + ADMIN tường minh] · +15 CWS guard **kèm chặn null==null lọt guard** `actorUserId is Guid`); build 0E + **suite 580/0 GIỮ** (lead đo); 0 test cũ bám 3 handler (lane verify trước)
- [!] wf: W6 đợt-2 `wf_131c8f87-356` test-specialist 5-PIN (+2 bonus: admin-inbox DR-4 + CreatedBy-null-guard) ĐANG CHẠY, đích ≥585 → reviewer security-wave → ship
- [ ] W5 (cầu KHKK→HĐ — cần setup WF tay TRƯỚC: type-3 + type-10 3-trạm Designer) → W7 (bản cứng 1-mốc @S161)
- [ ] W6 → W5 → W7 theo đồ thị plan-cha (sau W3)
- [ ] đợt-2 SAU khi wf về: test-specialist + database-agent (song song) → lead acceptance §③-B (build·test·sqlcmd 96·Down sạch·đo CỜ) → reviewer → commit/push → cicd-monitor 3-chân-kiềng

View File

@ -0,0 +1,40 @@
# sub-implementer-backend-0 — W6 Đường ống HĐ V2 (view + inbox + vai-trình)
> Run: `2026-07-29-S161-khkk-w6-duongong` · Spec: `.claude/workflows/runs/2026-07-29-S160-khkk-dryrun-plan/spec-wave-w6-duong-ong-hd-v2-29-07-2026.md`
> Luật lượt này: BE-only · 0 mig · KHÔNG commit/push/slnx · KHÔNG viết test (đợt-2) · KHÔNG đụng `fe-*/` · KHÔNG đụng Reject `:49-66` (O-A) · KHÔNG đụng `ContractSigningPlan*` (KHKK W1-W3 đã ship).
> Ghi TỪNG MỤC trong lúc làm (chống #53).
---
## §0 — ĐO TRƯỚC KHI SỬA (gate 5-anchor, đọc tươi 2026-07-29)
| Anchor (spec §③-A) | Đo thật | Khớp? | Nội dung |
|---|---|---|---|
| `ContractFeatures.cs:334-351` | `:334` `internal static List<ContractPhase> GetEligiblePhases(IReadOnlyList<string> userRoles)``:351` `return phases.ToList();` | ✅ | chữ ký CHỈ nhận role ⇒ không biết HĐ nào |
| `ContractFeatures.cs:421-430` | `:421` `private static readonly Dictionary<ContractPhase, string[]> PhaseActorRoles = new()``:430` `[DangDongDau] = [HrAdmin],` | ✅ | 7 key, **0 key `ChoDuyet`** |
| `ContractFeatures.cs:488-489` | `:488` `if (!isDrafter && !isEligibleByRole)` `:489` `throw new ForbiddenException("Bạn không có quyền xem HĐ này.")` | ✅ | 403 detail |
| `ContractWorkflowService.cs:73-78` | `:73` `if (!isAdmin && !isSystem` `:74` `&& !actorRoles.Contains(AppRoles.Drafter)` `:75` `&& !actorRoles.Contains(AppRoles.DeptManager))` `:77-78` throw Forbidden "không đủ quyền trình duyệt HĐ." | ✅ | guard trình |
| `ContractsController.cs:38-40` | `:38` `[HttpGet("inbox")]` `:39` `Inbox(CancellationToken ct)` `:40` `=> Ok(await mediator.Send(new GetMyInboxQuery(), ct));` | ✅ | endpoint inbox |
**Gate 5-anchor: PASS 5/5 content-exact.**
3 call-site `GetEligiblePhases` (grep `src/Backend`, đủ 3 — risk C "sửa chỉ 1/3"):
- `ContractFeatures.cs:301``ListContractsQueryHandler` (List)
- `ContractFeatures.cs:381``ListDeletedContractsQueryHandler` (ListDeleted, `IgnoreQueryFilters().Where(IsDeleted)`)
- `ContractFeatures.cs:486``GetContractQueryHandler` (Detail)
- *(`:441-442``PhaseActorRoles` của inbox — call-site THỨ 4 của nhánh phase, không phải của `GetEligiblePhases`)*
Khuôn nguồn để mirror (đọc tươi):
- PE detail V2-approver: `PurchaseEvaluationFeatures.cs:886-898` (`AnyAsync(l => l.Step!.ApprovalWorkflowId == awId && l.ApproverUserId == uid)` + `isDraftPhase` S89)
- PE inbox admin phase liệt tường minh: `PurchaseEvaluationFeatures.cs:731-742` (+ `ChoDuyet` `:740`)
- PE `v2InboxIds` rỗng cho admin: `PurchaseEvaluationFeatures.cs:746-748`
- PE `ResolveV2InboxIdsAsync` in-memory join: `PurchaseEvaluationFeatures.cs:817-852`
- KHKK (chính tao viết W2): `ContractSigningPlanFeatures.cs:229-264` (Resolve) + `:275-283` (`ResolveUserApprovalWorkflowIdsAsync`)
Nền tảng đã verify TRƯỚC khi code (chống bẫy "quên lọc IsDeleted" — risk C):
- `ContractConfiguration.cs:44` `b.HasQueryFilter(x => !x.IsDeleted)``db.Contracts` mặc-định ĐÃ loại HĐ xóa mềm ⇒ inbox + list + `ResolveV2InboxIdsAsync` tự an-toàn, KHÔNG cần `.Where(!IsDeleted)` tay (khác HRM).
- `Contract.cs:23/40/46` có đủ `ApprovalWorkflowId` / `CurrentWorkflowStepIndex` / `CurrentApprovalLevelOrder`; `:16` `DrafterUserId`.
- `BaseEntity.CreatedBy` kiểu **`Guid?`** (không phải string) ⇒ so trực tiếp với `actorUserId`.
- `grep tests/` cho `ContractV2Pipeline|GetMyInboxQuery|ListContractsQuery|GetContractQuery` = **0 hit** ⇒ 3 handler này hiện KHÔNG có test cũ nào bám ⇒ sửa không thể phá test cũ qua đường assert; rủi ro duy nhất là compile + suite tổng.
---