Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 52 additions & 25 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ The workflow engine is organized into 8 layers:
- `WorkflowBuilder` - Builder pattern for workflow construction

2. **Node Layer** (`com.codingapi.flow.node`)
- `IFlowNode` - Interface defining node lifecycle methods
- `BaseFlowNode` - Abstract base for all nodes
- `BaseAuditNode` - Abstract base for audit nodes (ApprovalNode, HandleNode)
- `IFlowNode` - Interface defining node lifecycle methods (including `strategyManager()`)
- `BaseFlowNode` - Abstract base for all nodes, manages both `actions` and `strategies`
- `BaseAuditNode` - Abstract base for audit nodes (ApprovalNode, HandleNode), simplified to use strategies for all configurations
- 11 node types: StartNode, EndNode, ApprovalNode, HandleNode, NotifyNode, ConditionBranchNode, ParallelBranchNode, RouterBranchNode, InclusiveBranchNode, DelayNode, TriggerNode, SubProcessNode

3. **Action Layer** (`com.codingapi.flow.action`)
- `IFlowAction` - Interface for node actions
3. **Action Layer** (`com.codingapi.flow.action`, `com.codingapi.flow.action.actions`)
- `IFlowAction` - Interface for node actions (including `copy()` method)
- `BaseAction` - Abstract base with `triggerNode()` for recursive node traversal
- 8 action types: PassAction, RejectAction, SaveAction, ReturnAction, TransferAction, AddAuditAction, DelegateAction, CustomAction
- 9 action types: DefaultAction, PassAction, RejectAction, SaveAction, ReturnAction, TransferAction, AddAuditAction, DelegateAction, CustomAction

4. **Record Layer** (`com.codingapi.flow.record`)
- `FlowRecord` - Execution record with states (TODO/DONE, RUNNING/FINISH/ERROR/DELETE)
Expand All @@ -87,27 +87,26 @@ The workflow engine is organized into 8 layers:
- `FlowAdvice` - Encapsulates approval parameters (advice, signKey, backNode, transferOperators)

6. **Manager Layer** (`com.codingapi.flow.node.manager`)
- `ActionManager` - Manages node actions
- `ActionManager` - Manages node actions (including `getAction(Class)`, `verifySession()`)
- `OperatorManager` - Manages node operators
- `FieldPermissionManager` - Manages form field permissions
- `StrategyManager` - Manages node strategies
- `StrategyManager` - Manages node strategies (including `loadOperators()`, `generateTitle()`, `verifySession()`)

7. **Strategy Layer** (`com.codingapi.flow.strategy`)
- `INodeStrategy` - Interface for node strategies
- MultiOperatorAuditStrategy, TimeoutStrategy, SameOperatorAuditStrategy, RecordMergeStrategy, ResubmitStrategy, AdviceStrategy
- `INodeStrategy` - Interface for node strategies (including `copy()`, `getId()`)
- 10 strategy types: MultiOperatorAuditStrategy, TimeoutStrategy, SameOperatorAuditStrategy, RecordMergeStrategy, ResubmitStrategy, AdviceStrategy, OperatorLoadStrategy, ErrorTriggerStrategy, NodeTitleStrategy, FormFieldPermissionStrategy

8. **Script Layer** (`com.codingapi.flow.script.runtime`)
- `ScriptRuntimeContext` - Groovy script execution environment
- OperatorMatchScript, OperatorLoadScript, NodeTitleScript, ConditionScript, ErrorTriggerScript
- OperatorMatchScript, OperatorLoadScript, NodeTitleScript, ConditionScript, ErrorTriggerScript, RejectActionScript

### Node Lifecycle (Critical for Understanding Flow)

When a node is executed, methods are called in this order:
1. `verifySession(session)` - Validate session parameters
1. `verifySession(session)` - Delegates to ActionManager and StrategyManager for validation
2. `continueTrigger(session)` - Returns true to continue to next node, false to generate records
3. `generateCurrentRecords(session)` - Generate FlowRecords for current node
4. `fillNewRecord(session, record)` - Fill new record data
5. `isDone(session)` - Check if node is complete (multi-person approval nodes need progress check)
3. `generateCurrentRecords(session)` - Generate FlowRecords for current node (uses StrategyManager.loadOperators() for audit nodes)
4. `fillNewRecord(session, record)` - Fill new record data (uses StrategyManager for audit nodes)
5. `isDone(session)` - Check if node is complete (uses StrategyManager for multi-person approval progress)

### Flow Execution Lifecycle

Expand All @@ -118,7 +117,7 @@ When a node is executed, methods are called in this order:
1. Validate request → Validate operator → Get record → Validate record state → Load workflow → Get current node → Get action → Build form data → Create session → Verify session → Execute action

**PassAction.run()** (typical action execution):
1. Check if node is done → Update current record → Generate subsequent records → Trigger next nodes → Save records → Push events
1. Check if node is done (via StrategyManager) → Update current record → Generate subsequent records → Trigger next nodes → Save records → Push events

### Parallel Branch Execution

Expand All @@ -131,12 +130,40 @@ When encountering `ParallelBranchNode`:

### Key Design Patterns

- **Builder Pattern**: `WorkflowBuilder`, `BaseNodeBuilder`, `AuditNodeBuilder` with singleton `builder()` method
- **Factory Pattern**: `NodeFactory.getInstance()`, `FlowActionFactory`
- **Strategy Pattern**: `INodeStrategy` for multi-operator approval, timeout, etc.
- **Template Method**: `BaseFlowNode` defines node lifecycle, `BaseAction` defines action execution
- **Singleton**: `NodeFactory`, `ScriptRuntimeContext`, `RepositoryContext` use static final instance
- **Chain of Responsibility**: `triggerNode()` recursively traverses subsequent nodes
- **Builder Pattern**: `WorkflowBuilder`, `BaseNodeBuilder`, `ActionBuilder` with singleton `builder()` method
- **Factory Pattern**: `NodeFactory.getInstance()` (uses reflection to call static `formMap()` methods), `NodeStrategyFactory`, `FlowActionFactory`
- **Strategy Pattern**: `INodeStrategy` with `StrategyManager` - strategy-driven node configuration (operators, titles, timeouts, permissions all via strategies)
- **Template Method**: `BaseFlowNode` defines node lifecycle, `BaseAction` defines action execution, `BaseStrategy` defines strategy template
- **Singleton**: `NodeFactory`, `ScriptRuntimeContext`, `RepositoryContext`, `GatewayContext` use static final instance
- **Chain of Responsibility**: `triggerNode()` recursively traverses subsequent nodes, `StrategyManager` iterates strategies to find matches
- **Composite Pattern**: Nodes contain multiple strategies and actions
- **Copy Pattern**: `INodeStrategy.copy()`, `IFlowAction.copy()`, `BaseFlowNode.setActions()`, `BaseFlowNode.setStrategies()` for incremental updates

### Strategy-Driven Node Configuration (Critical Architecture Change)

All node configurations are now implemented through strategies rather than direct properties:
- **Operator loading**: `OperatorLoadStrategy` with Groovy script
- **Node title**: `NodeTitleStrategy` with Groovy script
- **Timeout**: `TimeoutStrategy` with timeout value
- **Permissions**: `FormFieldPermissionStrategy` with field permission list
- **Error handling**: `ErrorTriggerStrategy` with Groovy script
- **Multi-person approval**: `MultiOperatorAuditStrategy` with type (SEQUENCE/MERGE/ANY/RANDOM_ONE)

The `StrategyManager` provides unified access to all strategies:
- `loadOperators(session)` - Load operators via OperatorLoadStrategy
- `generateTitle(session)` - Generate title via NodeTitleStrategy
- `getTimeoutTime()` - Get timeout via TimeoutStrategy
- `verifySession(session)` - Verify via various strategies

### Multi-Person Approval Implementation

The `MultiOperatorAuditStrategy.Type` enum defines four approval modes:
- **SEQUENCE**: Sequential approval, hides subsequent records until previous is done
- **MERGE**: Concurrent approval, requires percentage completion (configurable via `percent` property)
- **ANY**: Any one person approval, completes immediately when first person approves
- **RANDOM_ONE**: Random one person approval, randomly selects one person from the list

The `BaseAuditNode.isDone()` method implements the completion logic for each mode.

## Code Conventions

Expand All @@ -151,13 +178,13 @@ When encountering `ParallelBranchNode`:

- **Custom Nodes**: Extend `BaseFlowNode` or `BaseAuditNode`, implement `IFlowNode`
- **Custom Actions**: Extend `BaseAction`, implement `IFlowAction`
- **Custom Strategies**: Implement `INodeStrategy`
- **Custom Strategies**: Extend `BaseStrategy`, implement `INodeStrategy`
- **Custom Scripts**: Use `ScriptRuntimeContext` for Groovy execution
- **Event Listeners**: Listen to `FlowRecordStartEvent`, `FlowRecordTodoEvent`, `FlowRecordDoneEvent`, `FlowRecordFinishEvent`

## Documentation References

- **flow-engine-framework/src/test/Design.md** - Comprehensive architecture documentation with class design, lifecycle diagrams, and design patterns
- **flow-engine-framework/src/test/Design.md** - Comprehensive architecture documentation with updated class design, lifecycle diagrams, design patterns, and key implementation details
- **AGENTS.md** - Detailed coding guidelines and patterns
- **frontend/packages/flow-design/AGENTS.md** - Frontend library development
- **frontend/apps/app-pc/AGENTS.md** - Frontend app development
Expand Down
Loading