[CLAUDE] Domain: Chunk A — Mig 31 swap F2 storage Users→ApprovalWorkflowLevels (Approver scope ChoDuyet)
Mig 31 RefactorSkipToFinalToApproverLevel — 2 stage manual reorder: - ADD ApprovalWorkflowLevels.AllowApproverSkipToFinal bit NOT NULL DEFAULT 0 - DROP Users.AllowDrafterSkipToFinal (semantic mới khác hẳn — admin re-config qua Designer) - NO BACKFILL (Option A — accept lose 4 prod user value per K0-bis audit) Plan K refactor F2 semantic: Drafter from Nháp → Approver during ChoDuyet skip thẳng Cấp cuối. Mirror F3+F4 admin opt-in per-Approver-slot pattern (Mig 29 + Mig 30) reinforced 3× cumulative. Service line 121-157 F2 Drafter SUBMIT branch REMOVED stub (K2 sẽ add Approver F2 branch trong APPROVE STEP line ~393-525). TransitionAsync skipToFinal param 8th KEPT cho K2 repurpose. Application layer compile-break fix transient: UserDto field mapping + GET handler + LIST handler + SetUserAllowDrafterSkipToFinalCommandHandler NoOp + PurchaseEvaluationFeatures drafter flag → sentinel false. DTO + Command signature UNCHANGED (K2 chunk Chủ trì sẽ refactor DTO/Command theo plan). 4 prod user (fin.pp + pm.nv + nv.test + truong.nguyen) lose AllowDrafterSkipToFinal=true per bro Option A. Audit trail trong session log K8. Verify: - dotnet ef migrations add pass - dotnet ef database update Dev + Design pass (Mig 31 applied both DB) - dotnet build src/Backend/SolutionErp.Api production projects clean (0 err, 0 warn) - dotnet test SKIPPED per UAT mode (memory feedback_uat_skip_verify) — K7 chunk fix remaining PurchaseEvaluationWorkflowServiceReturnModeTests.cs:253 reference Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -118,43 +118,16 @@ public class PurchaseEvaluationWorkflowService(
|
||||
}
|
||||
evaluation.Phase = PurchaseEvaluationPhase.ChoDuyet;
|
||||
|
||||
// F2 (Mig 29 — S21 t5) — Drafter skip thẳng Cấp cuối. Permission
|
||||
// check moved sang `User.AllowDrafterSkipToFinal` (per-Drafter user,
|
||||
// không còn workflow-level Mig 28).
|
||||
// Admin bypass user flag check.
|
||||
if (skipToFinal && evaluation.ApprovalWorkflowId is Guid skipAwId)
|
||||
{
|
||||
if (!isAdmin)
|
||||
{
|
||||
if (actorUserId is null)
|
||||
throw new ConflictException("skipToFinal yêu cầu authenticated user.");
|
||||
var drafterUser = await userManager.FindByIdAsync(actorUserId.Value.ToString())
|
||||
?? throw new ConflictException("User không tồn tại.");
|
||||
if (!drafterUser.AllowDrafterSkipToFinal)
|
||||
throw new ConflictException(
|
||||
$"User '{drafterUser.FullName}' không được phép gửi thẳng Cấp cuối. " +
|
||||
"Liên hệ Admin để cấp quyền ở User Management.");
|
||||
}
|
||||
var wfSkip = await db.ApprovalWorkflows
|
||||
.Include(w => w.Steps).ThenInclude(s => s.Levels)
|
||||
.FirstOrDefaultAsync(w => w.Id == skipAwId, ct)
|
||||
?? throw new ConflictException("Workflow không tồn tại.");
|
||||
var finalStep = wfSkip.Steps.OrderBy(s => s.Order).LastOrDefault()
|
||||
?? throw new ConflictException("Workflow chưa có Bước nào.");
|
||||
var finalLevelOrder = finalStep.Levels.OrderBy(l => l.Order).LastOrDefault()?.Order
|
||||
?? throw new ConflictException($"Bước {finalStep.Order} chưa có Cấp nào.");
|
||||
evaluation.CurrentWorkflowStepIndex = wfSkip.Steps.Count - 1; // 0-based last step
|
||||
evaluation.CurrentApprovalLevelOrder = finalLevelOrder;
|
||||
comment = string.IsNullOrWhiteSpace(comment)
|
||||
? "[Drafter gửi thẳng Cấp cuối — skip Bước/Cấp trung gian]"
|
||||
: $"{comment} [Drafter gửi thẳng Cấp cuối — skip Bước/Cấp trung gian]";
|
||||
}
|
||||
else
|
||||
{
|
||||
evaluation.CurrentWorkflowStepIndex = 0;
|
||||
// Chỉ init levelOrder=1 nếu pin schema V2 (ApprovalWorkflowId set).
|
||||
evaluation.CurrentApprovalLevelOrder = evaluation.ApprovalWorkflowId is not null ? 1 : null;
|
||||
}
|
||||
// Mig 31 (S23 t1 Plan K Chunk A) — F2 Drafter SUBMIT skipToFinal branch
|
||||
// REMOVED stub. Semantic refactor: F2 cũ Drafter-skip-from-Nháp → mới
|
||||
// Approver-skip-during-ChoDuyet (storage move sang
|
||||
// ApprovalWorkflowLevels.AllowApproverSkipToFinal per-slot Approver).
|
||||
// TransitionAsync `bool skipToFinal` 8th param KEPT cho K2 sẽ repurpose
|
||||
// to APPROVE STEP branch (line ~393-525 V2 path).
|
||||
// K2 sẽ add Approver F2 branch trong APPROVE STEP (line ~393-525)
|
||||
evaluation.CurrentWorkflowStepIndex = 0;
|
||||
// Chỉ init levelOrder=1 nếu pin schema V2 (ApprovalWorkflowId set).
|
||||
evaluation.CurrentApprovalLevelOrder = evaluation.ApprovalWorkflowId is not null ? 1 : null;
|
||||
evaluation.SlaDeadline = dateTime.UtcNow.AddDays(7);
|
||||
await LogTransitionAsync(evaluation, fromPhase, PurchaseEvaluationPhase.ChoDuyet, actorUserId, decision, comment, ct);
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
Reference in New Issue
Block a user