|
| 1 | +# Phase 1 + 2: Foundation and Repository Pattern - Hexagonal Architecture |
| 2 | + |
| 3 | +This PR implements Phases 1 and 2 of the Pet architecture refactoring, establishing the foundation for hexagonal architecture (ports & adapters pattern) and adding a file-based repository implementation with full backward compatibility. |
| 4 | + |
| 5 | +## Phase 1: Foundation - Domain Layer |
| 6 | + |
| 7 | +**What's Included:** |
| 8 | + |
| 9 | +### Core Domain Models |
| 10 | +- `Snippet` struct with validation, tag matching |
| 11 | +- `Parameter` struct for command placeholders |
| 12 | +- Pure business logic with zero I/O dependencies |
| 13 | + |
| 14 | +### Repository Interface (Port) |
| 15 | +- `SnippetRepository` interface for storage abstraction |
| 16 | +- `MockRepository` for testing |
| 17 | +- Methods: `Load()`, `Save()`, `FindByDescription()`, `FindByID()`, `FilterByTags()` |
| 18 | + |
| 19 | +### Selector Interface (Port) |
| 20 | +- `Selector` interface for snippet selection abstraction |
| 21 | +- `DirectSelector` - exact match (for CLI-first mode) |
| 22 | +- `FirstMatchSelector` - auto-select first match |
| 23 | +- `MockSelector` for testing |
| 24 | + |
| 25 | +### ParameterInput Interface (Port) |
| 26 | +- `ParameterInput` interface for getting parameter values |
| 27 | +- `DefaultParameterInput` - uses defaults without prompting |
| 28 | +- `FlagParameterInput` - from CLI flags (with fallback to defaults) |
| 29 | +- `PositionalParameterInput` - from positional args |
| 30 | +- `MockParameterInput` for testing |
| 31 | + |
| 32 | +### SnippetService (Business Logic) |
| 33 | +- `ExtractParameters()` - parses `<param>`, `<param=default>`, `<param=|_v1_||_v2_|>` |
| 34 | +- `SubstituteParameters()` - replaces placeholders with values |
| 35 | +- Repository operations: `GetAll()`, `GetByDescription()`, `FilterByTags()`, `Create()`, `Update()`, `Delete()` |
| 36 | +- Full validation and error handling |
| 37 | +- Optimized: regex compiled once at package level |
| 38 | + |
| 39 | +## Phase 2: Repository Pattern - FileRepository |
| 40 | + |
| 41 | +**What's Included:** |
| 42 | + |
| 43 | +### FileRepository Implementation |
| 44 | +- Implements `domain.SnippetRepository` using TOML files |
| 45 | +- Does NOT depend on global `config.Conf` - receives paths via constructor for testability |
| 46 | +- TOML format identical to existing format (verified by compatibility tests) |
| 47 | +- Supports multi-file and directory configurations |
| 48 | + |
| 49 | +### Path Validation |
| 50 | +- Validates snippet filenames are in valid locations (main file or snippet directories) |
| 51 | +- Prevents Save/Load drift where snippets can be saved but not loaded back |
| 52 | +- Returns clear errors for invalid paths |
| 53 | + |
| 54 | +### Error Handling |
| 55 | +- Logs errors when files are inaccessible during directory walks |
| 56 | +- Doesn't silently skip corrupt/unreadable files |
| 57 | +- Proper error messages for all failure modes |
| 58 | + |
| 59 | +### Compatibility |
| 60 | +- Both old (`snippet/`) and new (`infrastructure/`) code can read/write the same files |
| 61 | +- Compatibility tests verify round-trip in both directions |
| 62 | +- Multiline commands preserved correctly |
| 63 | + |
| 64 | +## Migration Documentation |
| 65 | + |
| 66 | +**`MIGRATION.md`** documents: |
| 67 | +- Full 7-phase migration plan with architecture diagrams |
| 68 | +- How old and new code coexist during transition |
| 69 | +- Which GitHub issues will be resolved in Phase 6 |
| 70 | +- What changed (and didn't change) in each phase |
| 71 | + |
| 72 | +## Test Coverage |
| 73 | + |
| 74 | +### Phase 1 Tests (100+ test cases) |
| 75 | +- Core models: `Snippet`, `Parameter` validation and tag matching |
| 76 | +- All interfaces: Repository, Selector, ParameterInput with multiple implementations |
| 77 | +- SnippetService: parameter extraction, substitution, CRUD operations |
| 78 | +- Integration tests showing full workflows |
| 79 | + |
| 80 | +### Phase 2 Tests (20+ test cases) |
| 81 | +- FileRepository: load, save, multi-file, directories, error cases |
| 82 | +- Path validation: valid/invalid paths, drift prevention |
| 83 | +- Compatibility: bidirectional with existing `snippet.Snippets` |
| 84 | +- Round-trip: multiline commands, tags, all fields preserved |
| 85 | + |
| 86 | +**All tests passing** ✅ - both new tests and all existing project tests. |
| 87 | + |
| 88 | +## Files Added |
| 89 | + |
| 90 | +``` |
| 91 | +domain/ |
| 92 | +├── snippet.go, snippet_test.go # Core models |
| 93 | +├── repository.go, repository_test.go # Storage interface (port) |
| 94 | +├── selector.go, selector_test.go # Selection interface (port) |
| 95 | +├── parameter_input.go, parameter_input_test.go # Input interface (port) |
| 96 | +└── snippet_service.go, snippet_service_test.go # Business logic |
| 97 | +
|
| 98 | +infrastructure/ |
| 99 | +├── file_repository.go, file_repository_test.go # TOML storage implementation |
| 100 | +├── compat_test.go # Compatibility with existing code |
| 101 | +└── validation_test.go # Path validation tests |
| 102 | +
|
| 103 | +MIGRATION.md # Full migration plan |
| 104 | +``` |
| 105 | + |
| 106 | +## What Was NOT Changed |
| 107 | + |
| 108 | +All existing code remains untouched: |
| 109 | +- `snippet/` package - existing TOML loading/saving |
| 110 | +- `cmd/` package - all commands continue to work |
| 111 | +- `dialog/` package - gocui parameter dialog |
| 112 | +- `config/` package - configuration handling |
| 113 | + |
| 114 | +The `domain/` and `infrastructure/` packages are purely additive. |
| 115 | + |
| 116 | +## Benefits |
| 117 | + |
| 118 | +### 1. Testability ✅ |
| 119 | +- Core logic is pure functions - trivial to unit test |
| 120 | +- Mock adapters eliminate need for actual gocui/fzf in tests |
| 121 | +- Test coverage can be comprehensive |
| 122 | + |
| 123 | +### 2. Flexibility ✅ |
| 124 | +- Interfaces allow swapping implementations (interactive CUI vs direct CLI) |
| 125 | +- Easy to add new adapters (REST API, HTTP server) in future |
| 126 | +- Business logic changes don't affect UI and vice versa |
| 127 | + |
| 128 | +### 3. Performance ✅ |
| 129 | +- Regex compiled once at package level (not on every call) |
| 130 | +- Efficient file operations with proper error handling |
| 131 | + |
| 132 | +### 4. Maintainability ✅ |
| 133 | +- Clear separation of concerns |
| 134 | +- Easy to understand and modify |
| 135 | +- Well-documented with MIGRATION.md |
| 136 | + |
| 137 | +## What's Next |
| 138 | + |
| 139 | +### Phase 3: Parameter Input Abstraction (Planned) |
| 140 | +Refactor `dialog/` package to wrap gocui behind `ParameterInput` interface |
| 141 | + |
| 142 | +### Phase 4: Selector Abstraction (Planned) |
| 143 | +Wrap fzf/peco selection behind `Selector` interface |
| 144 | + |
| 145 | +### Phase 5: Refactor Commands (Planned) |
| 146 | +Update all commands in `cmd/` to use new architecture |
| 147 | + |
| 148 | +### Phase 6: CLI-First Features (Planned) |
| 149 | +Add direct execution flags: |
| 150 | +```bash |
| 151 | +pet exec "docker ps" |
| 152 | +pet exec -d "docker run" --param container=nginx --param port=8080 |
| 153 | +pet exec --first-match -q "docker" |
| 154 | +pet list --json |
| 155 | +pet new --command "ls -la" --tag list --description "List files" |
| 156 | +``` |
| 157 | + |
| 158 | +**This will resolve GitHub issues:** #73, #84, #117, #147, #164, #352 |
| 159 | + |
| 160 | +### Phase 7: Documentation & Polish (Planned) |
| 161 | +Update README, add architecture docs, prepare v2.0 release |
| 162 | + |
| 163 | +## Testing |
| 164 | + |
| 165 | +```bash |
| 166 | +# Run all tests |
| 167 | +go test ./... |
| 168 | + |
| 169 | +# Run domain tests |
| 170 | +go test ./domain/... -v |
| 171 | + |
| 172 | +# Run infrastructure tests (includes compatibility tests) |
| 173 | +go test ./infrastructure/... -v |
| 174 | + |
| 175 | +# Run with coverage |
| 176 | +go test ./... -cover |
| 177 | +``` |
| 178 | + |
| 179 | +--- |
| 180 | + |
| 181 | +**This PR is safe to merge** - it adds new, well-tested code but doesn't modify any existing functionality. All existing tests continue to pass. |
0 commit comments