Code Review Phase 3: Domain Layer — Pure Business Logic
Purpose: Review the framework-agnostic business logic. This layer has zero React or Redux dependencies — it contains the graph algorithms and ID generation that the rest of the app relies on.
Prerequisites: Phase 1 (Type System)
Estimated time: 1 hour
Files: 4
Files to Review (in order)
Implementation
Tests
Key Concepts
- TypeScript function overloads (
generateId(type: 'node'): NodeId) provide type-narrowed return types from a single function
- The bipartite graph constraint means connections must alternate between nodes and datasets — never node-to-node or dataset-to-dataset
buildDependencyGraph collapses the bipartite graph into an effective node-to-node dependency graph for cycle detection
Focus Areas
Next: Phase 4 (Redux Store & Slices) — depends on this phase
Code Review Phase 3: Domain Layer — Pure Business Logic
Purpose: Review the framework-agnostic business logic. This layer has zero React or Redux dependencies — it contains the graph algorithms and ID generation that the rest of the app relies on.
Prerequisites: Phase 1 (Type System)
Estimated time: 1 hour
Files: 4
Files to Review (in order)
Implementation
src/domain/IdGenerator.ts— ID generation functions with TypeScript function overloads, type re-exports fromtypes/ids.tssrc/domain/PipelineGraph.ts— Bipartite graph builder, DFS-based cycle detection, orphan detection (nodes/datasets with no connections)src/domain/index.ts— Barrel exportTests
src/domain/PipelineGraph.test.ts— 27 tests: graph building, cycle detection, orphan findingKey Concepts
generateId(type: 'node'): NodeId) provide type-narrowed return types from a single functionbuildDependencyGraphcollapses the bipartite graph into an effective node-to-node dependency graph for cycle detectionFocus Areas
generateNodeId()now usescrypto.randomUUID()with aDate.now()+ random fallback for environments without crypto support. Verify the fallback is adequate.detectCycleDFS: when a cycle is found, is the cycle path correctly extracted? Verify the DFS implementation handles all edge cases.parseIdTypeidentifies connections by checking if string contains BOTHnode-anddataset-— could this misfire on edge cases?findOrphanedNodesandfindOrphanedDatasetsuse a Set for O(1) lookup — verify correctnessgenerateCopyIdadds a random suffix — verify the format is consistent with ID type guards inids.tsPipelineGraph.test.ts— do the 27 tests cover all edge cases (empty graph, single node, self-loop, diamond dependency)?