[CLAUDE] App+Infra+Tests: W6 KHKK — duong ong HD V2 (view per-HD 3-site + inbox V2+ADMIN + guard trinh +PMH)
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m52s
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 5m52s
- View: vế isV2Approver per-HĐ ở CẢ 3 call-site GetEligiblePhases (:301/:381/:486) — không role-blanket, nháp-riêng-tư S89 giữ, deleted-view cùng vị ngữ - Inbox: ghép v2InboxIds precompute (mirror PE ResolveV2InboxIdsAsync) + nhánh ADMIN phase-list tường minh +ChoDuyet (DR-4/F-B13) — HĐ ChoDuyet vào inbox cả approver lẫn admin - Guard trình CWS:73-78: Drafter|DeptManager|người-tạo|Procurement + chặn null==null lọt guard (actorUserId is Guid); Reject :49-66 + vùng W3 :217-394 0-diff (O-A giữ) - tests +7 (587/0): 5 PIN + admin-inbox DR-4 + Submit 4-vế/null-trap - Reviewer: Trục 1-3 vai PASS 0-critical + 4-7 lead — 2 ghi-nhận owner: workflow-blanket-by-design độ rộng + Reject pre-existing AMPLIFIED (bán kính nổ tăng khi view mở) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@ -70,9 +70,22 @@ public class ContractWorkflowService(
|
||||
if ((fromPhase == ContractPhase.DangSoanThao || fromPhase == ContractPhase.TraLai)
|
||||
&& (targetPhase == ContractPhase.ChoDuyet || (!isAdmin && !isSystem)))
|
||||
{
|
||||
// [W6 S161] Nới vai được TRÌNH: `Drafter ∨ DeptManager ∨ người-tạo ∨ Procurement`.
|
||||
// Lỗ đo 07-29: nhân sự Phòng Mua hàng (role `Procurement`) bị 403 khi trình HĐ do
|
||||
// chính mình lập. Vẫn giữ 403 cho role NGOÀI 4 vế này.
|
||||
// 🔴 `actorUserId is Guid` là BẮT BUỘC, không được viết thẳng
|
||||
// `contract.CreatedBy == actorUserId`: cả hai đều `Guid?` ⇒ HĐ seed/legacy có
|
||||
// `CreatedBy == null` gặp actor null sẽ ra `null == null` = TRUE và lọt guard.
|
||||
// Xét cả `DrafterUserId` vì đó là field handler tạo HĐ gán tường minh
|
||||
// (`ContractFeatures.cs:96`), còn `CreatedBy` do `AuditingInterceptor.cs:45` gán —
|
||||
// HĐ nạp từ seed có thể trống ô sau.
|
||||
var isCreator = actorUserId is Guid actorId
|
||||
&& (contract.CreatedBy == actorId || contract.DrafterUserId == actorId);
|
||||
if (!isAdmin && !isSystem
|
||||
&& !actorRoles.Contains(AppRoles.Drafter)
|
||||
&& !actorRoles.Contains(AppRoles.DeptManager))
|
||||
&& !actorRoles.Contains(AppRoles.DeptManager)
|
||||
&& !actorRoles.Contains(AppRoles.Procurement)
|
||||
&& !isCreator)
|
||||
{
|
||||
throw new ForbiddenException(
|
||||
$"Role ({string.Join(",", actorRoles)}) không đủ quyền trình duyệt HĐ.");
|
||||
|
||||
Reference in New Issue
Block a user