diff --git a/CLAUDE.md b/CLAUDE.md index 50d2203c..d3d480b3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -59,44 +59,84 @@ pnpm run dev:app-pc - **packages/flow-pc** - PC display components - **packages/flow-mobile** - Mobile display components -### Core Workflow Concepts - -**Node Types** (11 types defined in `FlowNodeFactory`): -- StartNode, EndNode - Process boundaries -- ApprovalNode, HandleNode - Task processing -- NotifyNode - Notifications -- ConditionBranchNode, ParallelBranchNode, RouterBranchNode, InclusiveBranchNode - Control flow -- SubProcessNode - Nested workflows -- DelayNode, TriggerNode - Timing and events - -**Key Interfaces**: -- `IFlowNode` - All workflow nodes implement this -- `IFlowOperator` - User/operator abstraction -- `IFlowEdge` - Connections between nodes -- `IFlowButton` - Actions available on nodes - -**Builder Pattern** - Used extensively for creating workflows and forms: -```java -Workflow workflow = WorkflowBuilder.builder() - .title("Leave Request") - .node(startNode) - .node(approvalNode) - .build(); -``` +### Core Layered Architecture + +The workflow engine is organized into 8 layers: + +1. **Workflow Layer** (`com.codingapi.flow.workflow`) + - `Workflow` - Top-level container with nodes, edges, form definition + - `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) + - 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 + - `BaseAction` - Abstract base with `triggerNode()` for recursive node traversal + - 8 action types: 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) + - Tracks processId, nodeId, currentOperatorId, formData, parallel branch info + +5. **Session Layer** (`com.codingapi.flow.session`) + - `FlowSession` - Execution context with currentOperator, workflow, currentNode, currentAction, currentRecord, formData, advice + - `FlowAdvice` - Encapsulates approval parameters (advice, signKey, backNode, transferOperators) + +6. **Manager Layer** (`com.codingapi.flow.node.manager`) + - `ActionManager` - Manages node actions + - `OperatorManager` - Manages node operators + - `FieldPermissionManager` - Manages form field permissions + - `StrategyManager` - Manages node strategies + +7. **Strategy Layer** (`com.codingapi.flow.strategy`) + - `INodeStrategy` - Interface for node strategies + - MultiOperatorAuditStrategy, TimeoutStrategy, SameOperatorAuditStrategy, RecordMergeStrategy, ResubmitStrategy, AdviceStrategy -### Form System +8. **Script Layer** (`com.codingapi.flow.script.runtime`) + - `ScriptRuntimeContext` - Groovy script execution environment + - OperatorMatchScript, OperatorLoadScript, NodeTitleScript, ConditionScript, ErrorTriggerScript -Forms have a main form with optional sub-forms. Fields support: -- Types: string, int, and others -- Permissions: READ, WRITE, NONE at field level -- Validation rules via metadata +### Node Lifecycle (Critical for Understanding Flow) -### Script Execution +When a node is executed, methods are called in this order: +1. `verifySession(session)` - Validate session parameters +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) -Groovy scripts run in `ScriptRuntimeContext` with: -- Variable injection for workflow data -- Operator matching scripts for routing decisions -- Custom function support +### Flow Execution Lifecycle + +**FlowCreateService** (starting a workflow): +1. Validate request → Get workflow definition → Verify workflow → Create/get backup → Validate creator → Build form data → Create start session → Verify session → Generate records → Save records → Push events + +**FlowActionService** (executing an action): +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 + +### Parallel Branch Execution + +When encountering `ParallelBranchNode`: +1. `filterBranches()` analyzes and finds the convergence end node +2. Record parallel info (parallelBranchNodeId, parallelBranchTotal, parallelId) in FlowRecord +3. Execute all branches simultaneously (generate records for each) +4. At convergence node, `isWaitParallelRecord()` checks if all branches have arrived +5. Once all arrive, clear parallel info and continue + +### 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 ## Code Conventions @@ -107,8 +147,17 @@ Groovy scripts run in `ScriptRuntimeContext` with: - Lombok annotations for boilerplate (`@Data`, `@Getter`, `@Setter`) - JUnit 5 with static assertions: `import static org.junit.jupiter.api.Assertions.*;` +## Extension Points + +- **Custom Nodes**: Extend `BaseFlowNode` or `BaseAuditNode`, implement `IFlowNode` +- **Custom Actions**: Extend `BaseAction`, implement `IFlowAction` +- **Custom Strategies**: 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 - **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