refactor: structured DuplicateContentError and promote.go helpers#264
refactor: structured DuplicateContentError and promote.go helpers#264nvandessel merged 4 commits intomainfrom
Conversation
Replace fragile string-parsing of duplicate error messages with a structured DuplicateContentError type in the store package. Callers now use errors.As instead of extractDuplicateNodeID string parsing. Also extract getTargetNode and mergeSourceEvents helpers to reduce duplication across executeAbsorb, executeSupersede, and executeSupplement. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #264 +/- ##
==========================================
+ Coverage 78.69% 78.78% +0.08%
==========================================
Files 185 186 +1
Lines 18702 18685 -17
==========================================
+ Hits 14718 14721 +3
+ Misses 2752 2739 -13
+ Partials 1232 1225 -7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Greptile SummaryThis PR cleanly replaces the fragile Key changes:
Confidence Score: 5/5Safe to merge — refactoring is correct, all tests pass, and the two findings are minor style suggestions All identified issues are P2 (a missing defensive empty-string guard that was never exercised in practice, and multi-field struct literals that deviate from gofmt convention). No logic bugs, no data-integrity risks, and the new DuplicateContentError type is backward-compatible with the existing ErrDuplicateContent sentinel. Score stays at 5 per the guidance that P2-only PRs should not be scored below 5. No files require special attention — all changes are consistent and well-tested
|
| Filename | Overview |
|---|---|
| internal/store/store.go | Adds DuplicateContentError struct with Error() and Is() methods, preserving backward-compat with ErrDuplicateContent sentinel via the Is hook |
| internal/store/memory.go | AddNode now returns &DuplicateContentError{ExistingID: id} directly instead of a fmt.Errorf wrapping; clean change |
| internal/store/sqlite.go | Same structured-error swap as memory.go — returns &DuplicateContentError{ExistingID} from addBehaviorWith |
| internal/consolidation/promote.go | Replaces string-parsed ErrDuplicateContent with errors.As, extracts getTargetNode and mergeSourceEvents helpers, removes the empty-ID guard on pendingToActual mapping; minor: multi-field struct literals on one line |
| internal/consolidation/promote_test.go | Good coverage added for getTargetNode (not-found, found, store-error) and mergeSourceEvents (dedup, empty, non-string); plus integration tests for unknown strategy and skip path |
| internal/store/store_test.go | New test file verifying DuplicateContentError.Error(), errors.Is, and errors.As — comprehensive unit coverage for the new type |
Sequence Diagram
sequenceDiagram
participant P as Promote
participant S as GraphStore
P->>S: AddNode(ctx, node)
alt duplicate canonical content
S-->>P: &DuplicateContentError{ExistingID}
P->>P: errors.As → dupErr.ExistingID
P->>P: pendingToActual[pendingID] = existingID
else success
S-->>P: nodeID, nil
P->>P: pendingToActual[pendingID] = node.ID
end
P->>P: getTargetNode(ctx, s, targetID)
P->>S: GetNode(ctx, targetID)
S-->>P: *Node or nil
alt nil → not found
P-->>P: error "target node not found"
else store error
P-->>P: fmt.Errorf wrap
else found
P-->>P: *existing (value copy)
end
P->>P: mergeSourceEvents(existing, incoming)
Note over P: dedup via seen map, append new events
P-->>P: []interface{} merged list
Reviews (4): Last reviewed commit: "Merge branch 'main' into refactor/promot..." | Re-trigger Greptile
- Rename new parameter to incoming in mergeSourceEvents (P2-1) - Remove unnecessary intermediate pointer in executeAbsorb (P2-2) - Add tests for DuplicateContentError, getTargetNode, mergeSourceEvents - Add tests for unknown merge strategy and skip path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DuplicateContentError is defined in PR #264, not this branch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* refactor: extract floopDirExists and logDecision helpers Extract floopDirExists(root) bool in cmd_hook.go to replace 4 instances of filepath.Join + os.Stat + os.IsNotExist. Add logDecision(fields) method on SubagentClient in subagent.go to encapsulate the nil-check on the decisions logger, replacing 7 occurrences. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: add coverage for detectAvailability CLI-not-found path Covers the logDecision call in detectAvailability when inCLISession() returns true but findCLI() returns empty, achieving 100% patch coverage for the logDecision helper refactoring. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address Greptile P2s and add coverage for promote helpers - Rename `new` parameter to `incoming` in mergeSourceEvents to avoid shadowing Go built-in (P2-1) - Remove unnecessary intermediate pointer in executeAbsorb — use value returned by getTargetNode directly (P2-2) - Add tests for DuplicateContentError.Error() and Is() methods - Add tests for getTargetNode, mergeSourceEvents helpers - Add tests for unknown merge strategy and skip path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove store_test.go added to wrong branch DuplicateContentError is defined in PR #264, not this branch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Covers the GetNode error return in getTargetNode using a mock store that returns an error, bringing the helper to 100% coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
extractDuplicateNodeIDstring-parsing withstore.DuplicateContentErrorstruct. Bothsqlite.goandmemory.gonow return&DuplicateContentError{ExistingID: id}instead offmt.Errorfwrapping. Callers useerrors.Asto extract the existing node ID.getTargetNodehelper: Extract repeated fetch-and-nil-check boilerplate fromexecuteAbsorb,executeSupersede, andexecuteSupplementinto a shared helper.mergeSourceEventshelper: Extract duplicated source-event deduplication loops fromexecuteAbsorbandexecuteSupersedeinto a shared helper.Test plan
go test ./internal/store/... ./internal/consolidation/... -v— all passgo test ./...— only pre-existing lancedb linker failures (unrelated)go fmt ./...— clean🤖 Generated with Claude Code