Skip to content

Refactor: Extract operations layer for improved testing and maintainability#4

Merged
jlaneve merged 3 commits intomainfrom
refactor/operations-layer-architecture
Jul 15, 2025
Merged

Refactor: Extract operations layer for improved testing and maintainability#4
jlaneve merged 3 commits intomainfrom
refactor/operations-layer-architecture

Conversation

@jlaneve
Copy link
Copy Markdown
Owner

@jlaneve jlaneve commented Jul 15, 2025

Summary

  • Created new internal/operations/ layer to centralize business logic
  • Extracted duplicated code from CLI commands into reusable operations
  • Added comprehensive test coverage (85.9%) for core business logic
  • Eliminated major code duplication across 13+ locations

New Operations Layer

  • SessionOperations: Session CRUD, lookup, and recreation logic
  • CleanupOperations: Comprehensive cleanup with detailed stats
  • StatusFormat: Unified formatting for tmux/claude/git status

Refactored CLI Commands

  • cwt new: Uses operations for session creation
  • cwt delete: Uses operations for session lookup and deletion
  • cwt cleanup: Completely rewritten using operations layer
  • cwt attach: Uses operations for session recreation
  • cwt list: Uses operations for formatting and session retrieval
  • cwt status: Uses operations for consistent formatting

Code Elimination

  • Removed duplicate FindSessionByName logic (13+ instances)
  • Removed duplicate findClaudeExecutable functions (3 instances)
  • Removed duplicate formatting functions (80+ lines from list.go)
  • Removed duplicate session recreation logic (attach.go)

Testing Improvements

  • Added 22 comprehensive test cases for operations layer
  • Mock-based testing for clean isolation
  • Edge case coverage for error scenarios
  • Improved overall project test coverage significantly

Architecture Benefits

  • Single source of truth for business logic
  • Clean separation of CLI parsing vs business operations
  • Reusable operations for future TUI integration
  • Consistent error handling patterns
  • Future-proof for additional CLI commands

🤖 Generated with Claude Code

…bility

## Summary
- Created new `internal/operations/` layer to centralize business logic
- Extracted duplicated code from CLI commands into reusable operations
- Added comprehensive test coverage (85.9%) for core business logic
- Eliminated major code duplication across 13+ locations

## New Operations Layer
- **SessionOperations**: Session CRUD, lookup, and recreation logic
- **CleanupOperations**: Comprehensive cleanup with detailed stats
- **StatusFormat**: Unified formatting for tmux/claude/git status

## Refactored CLI Commands
- `cwt new`: Uses operations for session creation
- `cwt delete`: Uses operations for session lookup and deletion
- `cwt cleanup`: Completely rewritten using operations layer
- `cwt attach`: Uses operations for session recreation
- `cwt list`: Uses operations for formatting and session retrieval
- `cwt status`: Uses operations for consistent formatting

## Code Elimination
- Removed duplicate `FindSessionByName` logic (13+ instances)
- Removed duplicate `findClaudeExecutable` functions (3 instances)
- Removed duplicate formatting functions (80+ lines from list.go)
- Removed duplicate session recreation logic (attach.go)

## Testing Improvements
- Added 22 comprehensive test cases for operations layer
- Mock-based testing for clean isolation
- Edge case coverage for error scenarios
- Improved overall project test coverage significantly

## Architecture Benefits
- Single source of truth for business logic
- Clean separation of CLI parsing vs business operations
- Reusable operations for future TUI integration
- Consistent error handling patterns
- Future-proof for additional CLI commands

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jul 15, 2025

Claude finished @jlaneve's task —— View job


Claude Code is reviewing this PR…

Review Tasks

  • Read repository guidelines (CLAUDE.md)
  • Review new operations layer architecture
  • Analyze session operations implementation
  • Review cleanup operations and logic
  • Check formatting operations consistency
  • Evaluate test coverage and quality
  • Review refactored CLI command integration
  • Assess code quality and best practices
  • Check for potential bugs or issues
  • Evaluate performance considerations
  • Review security implications
  • Provide comprehensive review feedback

Code Review

✅ Overall Assessment: Excellent Refactoring

This is a high-quality refactoring that significantly improves the codebase's maintainability and testability. The new operations layer follows solid architectural principles and eliminates substantial code duplication.

🏗️ Architecture & Design

Strengths:

  • Clean separation of concerns: CLI layer handles user interaction, operations layer contains business logic
  • Consistent dependency injection: Operations constructors take *state.Manager for clean testing
  • Single responsibility: Each operations file has a focused purpose (sessions, cleanup, formatting)
  • Future-proof design: Easy to extend for the planned TUI in Phase 2

Suggestions:

  • Consider adding interface definitions for operations (SessionOperator, CleanupOperator) to enable easier mocking in higher-level tests
  • The operations layer could benefit from a factory pattern or registry for consistency

🔒 Security (Excellent)

Strong security practices found:

  • Path validation in isValidWorktreeName() and isPathWithinDataDir() prevents directory traversal
  • Command injection prevention through input sanitization in isValidExecutablePath()
  • Comprehensive dangerous character filtering for shell metacharacters
  • Proper path cleaning using filepath.Clean() for normalization

Security validation functions are thorough:

// internal/operations/cleanup.go:216-242
func isValidWorktreeName(name string) bool {
    // Excellent coverage of attack vectors
}

// internal/operations/sessions.go:115-137  
func isValidExecutablePath(path string) bool {
    // Good shell injection prevention
}

🧪 Test Coverage (Very Good)

Strengths:

  • 22 comprehensive test cases covering core business logic
  • Mock-based testing with proper isolation using tmux.NewMockChecker(), etc.
  • Edge case coverage for error scenarios and security validation
  • Proper resource cleanup with t.TempDir() and defer manager.Close()

Areas for improvement:

  • Missing integration tests for the full CLI → Operations → State flow
  • FindClaudeExecutable() test acknowledges limitation but could be more robust
  • Consider table-driven tests for formatter functions to reduce repetition

🐛 Potential Issues

Minor Issues:

  1. Error handling inconsistency (internal/operations/sessions.go:84):
if existingSessionID, err := s.stateManager.GetClaudeChecker().FindSessionID(session.Core.WorktreePath); err == nil && existingSessionID != "" {

This swallows errors. Consider logging or handling the error case.

  1. Potential race condition in cleanup operations - no atomic cleanup transaction if multiple operations fail

  2. Resource leak potential in RecreateDeadSession() - if tmux creation fails after finding Claude session, no rollback

Suggestions:

  1. Add context support for cancellation:
func (s *SessionOperations) CreateSessionWithContext(ctx context.Context, name string) error
  1. Consider adding operation result types instead of just error returns:
type CreateSessionResult struct {
    Session *types.Session
    Warnings []string
}

⚡ Performance

Good performance characteristics:

  • Efficient session lookup with map-based checks in cleanup operations
  • Minimal external calls - operations batch system interactions
  • Proper resource cleanup prevents memory leaks

Considerations:

  • Multiple calls to DeriveFreshSessions() in cleanup could be optimized with caching
  • Large session lists might benefit from pagination in future TUI

🎯 Code Quality

Excellent practices:

  • Consistent error wrapping with context: fmt.Errorf("context: %w", err)
  • Clear function naming and documentation
  • Proper encapsulation with unexported helper functions
  • Good use of Go idioms (builder pattern in formatting, proper slice initialization)

Minor improvements:

  • Some functions could benefit from more granular error types
  • Consider adding metric collection points for observability

📊 Test Quality Deep Dive

Well-structured test files:

  • sessions_test.go: 295 lines, covers CRUD operations and security validation
  • cleanup_test.go: 267 lines, comprehensive cleanup scenarios
  • formatting_test.go: 275 lines, thorough formatting edge cases

Good testing patterns:

// Proper setup and teardown
tmpDir := t.TempDir()
defer manager.Close()

// Descriptive test names
func TestIsValidWorktreeName(t *testing.T)

// Comprehensive input validation testing
tests := []struct {
    name     string
    input    string  
    expected bool
}

🔄 Refactoring Impact

Positive changes:

  • Eliminated 13+ instances of duplicate FindSessionByName logic
  • Removed 3 instances of duplicate findClaudeExecutable functions
  • Consolidated 80+ lines of formatting code
  • Unified error handling patterns across CLI commands

Clean CLI integration:

// Before: 200+ lines in cleanup.go
// After: 85 lines using operations layer
cleanupOps := operations.NewCleanupOperations(sm)
stats, err := cleanupOps.FindAndCleanupStaleResources(dryRun)

🚀 Recommendations

Immediate (for this PR):

  1. Address error swallowing in RecreateDeadSession()
  2. Add integration test for at least one complete CLI flow
  3. Consider atomic cleanup transaction pattern

Future enhancements:

  1. Add interfaces for operations to enable better mocking
  2. Implement context support for cancellation
  3. Add observability hooks for metrics/logging
  4. Consider result types instead of just error returns

🏆 Summary

This is an exemplary refactoring that significantly improves code quality while maintaining all existing functionality. The new operations layer provides a solid foundation for future features (TUI, enhanced testing) and eliminates major technical debt.

Key wins:

  • ✅ Excellent test coverage (85.9%)
  • ✅ Strong security practices
  • ✅ Clean architecture with proper separation
  • ✅ Significant code deduplication
  • ✅ Future-proof design for planned features

Recommendation: Approve with minor suggestions

The code quality is high, security practices are excellent, and the architectural improvements are substantial. The minor issues identified are non-blocking and can be addressed in follow-up PRs.

jlaneve and others added 2 commits July 14, 2025 23:34
## Formatting Fixes
- Fixed Go formatting issues across all files
- Applied `go fmt ./...` to ensure consistent formatting
- All tests now pass without formatting errors

## CI Workflow Improvements
- Separated CI into 3 distinct jobs for clarity:
  - **Code Quality**: Formatting, go mod tidy, linting (go vet)
  - **Build**: Compilation check
  - **Tests**: Test execution with coverage
- Added clear emojis and status messages for each step
- Jobs run in parallel for faster feedback
- Easy to identify which specific area is failing

## Benefits
- Faster identification of formatting vs test failures
- Parallel execution improves CI speed
- Clear visual feedback with emojis and status messages
- Better developer experience with specific error messages

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Addresses security issues identified in PR #4 review:
- Add path validation in FindClaudeExecutable() to prevent directory traversal attacks
- Add command injection prevention in removeWorktree() function
- Implement isValidExecutablePath() to validate Claude executable paths
- Implement isValidWorktreeName() and isPathWithinDataDir() for worktree safety
- Add comprehensive test coverage for all security validation functions

Security mitigations:
- Reject paths with "..", null bytes, and shell metacharacters
- Allow $HOME expansion only at path start for legitimate use
- Validate worktree names against command injection patterns
- Ensure worktree paths stay within expected data directory boundaries
- Reject names starting with dash to prevent flag injection

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jlaneve jlaneve merged commit 04d747e into main Jul 15, 2025
4 checks passed
@jlaneve jlaneve deleted the refactor/operations-layer-architecture branch July 15, 2025 03:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant