1+ using ModularityKit . Mutator . Abstractions . Context ;
2+ using ModularityKit . Mutator . Abstractions . Engine ;
3+ using WorkflowApprovals . Mutations ;
4+ using WorkflowApprovals . State ;
5+
6+ namespace WorkflowApprovals . Scenarios ;
7+
8+ /// <summary>
9+ /// HappyPathScenario
10+ ///
11+ /// Demonstrates a "happy path" execution of an approval workflow using <see cref="IMutation{TState}"/>
12+ /// and <see cref="StartApprovalMutation"/> where all steps are approved successfully.
13+ ///
14+ /// Scenario Details:
15+ /// - Starts a new approval workflow using <see cref="ApproveStepMutation"/>.
16+ /// - Sequentially approves each step in the workflow using <see cref="MutationContext.System"/>.
17+ /// - Uses <see cref="MutationContext"/> to provide system metadata and correlation ID for audit purposes.
18+ /// - Logs success and failure for each mutation.
19+ /// - Works with <see cref="ApprovalWorkflowState"/> which tracks workflow steps and their approval status.
20+ ///
21+ /// Key Steps:
22+ /// 1. Initialize <see cref="StartApprovalMutation"/> as empty workflow state.
23+ /// 2. Start workflow with multiple steps via <see cref="IMutationEngine"/>.
24+ /// 3. Sequentially approve each step using predefined approvers.
25+ /// 4. Update workflow state after each mutation.
26+ /// 5. Print final state of all steps, including approved or rejected information.
27+ ///
28+ /// Example Use Case:
29+ /// - Simulating normal workflow progression for testing or documentation purposes.
30+ /// - Verifying that policies allow proper step approvals in sequence.
31+ /// - Demonstrating auditability and traceability with correlation IDs and system metadata.
32+ ///
33+ /// Notes:
34+ /// - If a mutation is blocked due to a policy decision, the scenario logs the blocking reason.
35+ /// - This scenario assumes all mutations succeed under normal conditions.
36+ /// - Can be extended with rejection scenarios or conditional approvals for more complex workflows.
37+ /// </summary>
38+ internal static class HappyPathScenario
39+ {
40+ internal static async Task Run ( IMutationEngine engine )
41+ {
42+ Console . WriteLine ( "\n === Happy Path Scenario ===" ) ;
43+
44+ var state = new ApprovalWorkflowState ( ) ;
45+
46+ var ctx = MutationContext . System ( "Start workflow" , correlationId : "workflow-123" ) ;
47+
48+ var start = new StartApprovalMutation ( "initiator" , [ "Step1" , "Step2" , "Step3" ] , ctx ) ;
49+ var result = await engine . ExecuteAsync ( start , state ) ;
50+ state = result . NewState ! ;
51+
52+ var approvers = new [ ] { "alice" , "bob" , "alice" } ;
53+
54+ for ( var i = 0 ; i < state . Steps . Count ; i ++ )
55+ {
56+ var approve = new ApproveStepMutation ( i , approvers [ i ] , ctx ) ;
57+ var res = await engine . ExecuteAsync ( approve , state ) ;
58+ if ( res . IsSuccess )
59+ state = res . NewState ! ;
60+ else
61+ {
62+ Console . WriteLine ( $ "✗ Step { i } blocked:") ;
63+ foreach ( var dec in res . PolicyDecisions )
64+ Console . WriteLine ( $ " { dec . PolicyName } – { dec . Reason } ") ;
65+ }
66+ }
67+
68+ Console . WriteLine ( "Workflow final state:" ) ;
69+ for ( var i = 0 ; i < state . Steps . Count ; i ++ )
70+ {
71+ var s = state . Steps [ i ] ;
72+ Console . WriteLine ( $ " Step{ i } : { s . Status } by { ( s . ApprovedBy ?? s . RejectedBy ?? "-" ) } ") ;
73+ }
74+ }
75+ }
0 commit comments