7.7 KiB
| phase | plan | type |
|---|---|---|
| 16-store-modularization | 2 | execute |
Purpose: The execution logic (~800 lines) is the largest section and most complex. Extracting it enables focused testing and cleaner separation of concerns between state management and execution orchestration. Output: New execution module with executeWorkflow, regenerateNode, and supporting execution utilities.
<execution_context> ~/.claude/get-shit-done/workflows/execute-phase.md ~/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/16-store-modularization/16-01-PLAN.md @src/store/workflowStore.tsDependencies from 16-01:
- localStorage utilities extracted
- nodeDefaults module exists
Execution Logic Analysis (~800 lines): The executeWorkflow and regenerateNode functions are tightly coupled to store state but can be extracted as action creators that receive state getters/setters. Key components:
- Topological sort algorithm (~30 lines)
- Node execution switch statement (~600 lines for all node types)
- API call patterns (repeated for each provider)
- Logger calls throughout
- State updates via updateNodeData
-
Extract topologicalSort function:
- Takes nodes and edges as input
- Returns sorted WorkflowNode array
- Throws on cycle detection
-
Extract buildProviderHeaders function:
- Takes provider type and providerSettings
- Returns headers object with API key headers
- Consolidates the repeated header building logic from executeWorkflow/regenerateNode
-
Extract getSourceOutput helper:
- Takes a WorkflowNode
- Returns { type: "image" | "text" | "video", value: string | null }
- Currently duplicated in getConnectedInputs
-
Export types:
- ExecutionResult = { success: boolean; error?: string; data?: unknown }
- NodeExecutionContext = { nodeId: string; get: () => StoreState; set: (partial: Partial) => void }
These are pure functions that don't directly depend on Zustand, making them testable. npm run build succeeds, new module compiles without errors Execution utilities extracted, types defined, build passes
Task 2: Extract node executors src/store/execution/nodeExecutors.ts Create src/store/execution/nodeExecutors.ts with individual node type executors:-
Create executor type:
type NodeExecutor = ( node: WorkflowNode, context: { getConnectedInputs: (nodeId: string) => ConnectedInputs; updateNodeData: (nodeId: string, data: Partial<WorkflowNodeData>) => void; get: () => WorkflowStoreState; set: (partial: Partial<WorkflowStoreState>) => void; providerSettings: ProviderSettings; } ) => Promise<{ continue: boolean; error?: string }>; -
Extract executors for each node type:
- executeImageInput (no-op, returns continue: true)
- executeAnnotation
- executePrompt (no-op)
- executeNanoBanana (image generation)
- executeGenerateVideo (video generation)
- executeLlmGenerate (text generation)
- executeSplitGrid
- executeOutput
-
Create nodeExecutorMap:
const nodeExecutorMap: Record<NodeType, NodeExecutor> = { ... } -
Export executeNode function that dispatches to the correct executor
This keeps the individual node logic but allows testing each executor in isolation. npm run build succeeds, no TypeScript errors Node executors extracted as individual functions with shared interface
Task 3: Refactor executeWorkflow to use extracted modules src/store/workflowStore.ts Update executeWorkflow in workflowStore.ts to use the extracted modules:-
Import from execution/utils.ts:
- topologicalSort
- buildProviderHeaders
-
Import from execution/nodeExecutors.ts:
- executeNode
-
Refactor executeWorkflow to use the imported utilities:
- Replace inline topological sort with topologicalSort()
- Replace switch statement with executeNode() calls
- Keep the overall orchestration logic (pause handling, locked groups, logging) in the store
-
Refactor regenerateNode similarly:
- Use buildProviderHeaders
- Could call individual executors but for now keep inline (regenerate has slightly different flow)
-
Ensure getConnectedInputs stays in the store (it needs edge state)
The goal is to reduce executeWorkflow from ~800 lines to ~200 lines of orchestration logic. npm run build succeeds, npm test passes, manual test of workflow execution works executeWorkflow refactored to ~200 lines, uses extracted modules, all tests pass
Task 4: Add unit tests for execution modules src/store/execution/__tests__/utils.test.ts, src/store/execution/__tests__/nodeExecutors.test.ts Create comprehensive tests for the extracted execution modules:-
Create src/store/execution/tests/utils.test.ts:
- Test topologicalSort with simple linear graph (A -> B -> C)
- Test topologicalSort with branching graph (A -> B, A -> C, B -> D, C -> D)
- Test topologicalSort throws on cycle detection (A -> B -> C -> A)
- Test topologicalSort with disconnected nodes
- Test buildProviderHeaders returns correct headers for each provider type
- Test buildProviderHeaders with missing API keys returns base headers only
- Test getSourceOutput for each node type returns correct type/value
-
Create src/store/execution/tests/nodeExecutors.test.ts:
- Test executeImageInput returns { continue: true } (no-op)
- Test executePrompt returns { continue: true } (no-op)
- Test executeAnnotation updates outputImage when sourceImage provided
- Test executeOutput updates node data with connected content
- Test executeNanaBanana handles missing text input (returns error)
- Test executeLlmGenerate handles missing text input (returns error)
- Mock fetch for API call tests
- Mock updateNodeData to verify state updates
Focus on testing the pure logic and error cases. API success paths can use mocked fetch responses. npm test passes with new tests, coverage report shows execution modules covered Unit tests added for execution utilities and node executors, all tests pass
Before declaring plan complete: - [ ] `npm run build` succeeds without errors - [ ] `npm test` passes all tests (existing + new execution module tests) - [ ] executeWorkflow function reduced from ~800 to ~200 lines - [ ] Workflow execution still works (test with a simple prompt -> generate -> output flow) - [ ] regenerateNode still works - [ ] Error handling preserved - [ ] topologicalSort has test coverage including cycle detection - [ ] buildProviderHeaders has test coverage for all provider types - [ ] Node executors have test coverage for error cases<success_criteria>
- All tasks completed
- All verification checks pass
- executeWorkflow is significantly shorter and more readable
- Node execution logic is isolated and testable
- Execution modules have comprehensive test coverage
- No regression in workflow execution behavior </success_criteria>