Skip to content

refactor: fix version comparison bug and extract DRY helpers#71

Merged
nathanhuh merged 4 commits intomainfrom
refactor/review-p1-p2
Apr 6, 2026
Merged

refactor: fix version comparison bug and extract DRY helpers#71
nathanhuh merged 4 commits intomainfrom
refactor/review-p1-p2

Conversation

@nathanhuh
Copy link
Copy Markdown
Contributor

Summary

Address the top 3 priorities from the /senior-review code quality report:

Priority 1 — Fix version comparison bug

  • IsNewer() used lexicographic string comparison (l > c), causing "0.9.0" > "0.10.0" to be true
  • Replaced with compareVersions() that splits on . and compares segments as integers
  • Added 3 test cases for multi-digit version segments

Priority 2 — Extract generic filter helpers

  • New filter.go with applyFilter[T Filterable]() and handleFilterKey()
  • Deleted 7 duplicate applyXxxFilter() functions across screens
  • Collapsed 8 filter-input handlers from 18 to 7 lines each (~180 lines removed)

Priority 3 (partial) — Extract Update() message handlers

  • Extracted 7 per-domain handleXxxMsg() functions to respective screen files
  • Update() reduced from 374 → 119 lines (68% reduction)
  • app.go reduced from 1,076 → 816 lines

Also includes:

  • /refactor-review skill for running refactorings from review reports
  • .claude/reports/ added to .gitignore

Validation

  • make test — all tests pass (no behavior changes)
  • make build — compiles cleanly
  • Pure refactor: zero behavior changes, all existing tests unchanged

- Replace lexicographic string comparison with compareVersions()
  that splits on "." and compares each segment as integers
- Fixes bug where "0.9.0" > "0.10.0" was true (string comparison)
- Add 3 test cases for multi-digit version segments
Filter DRY cleanup:
- Add filter.go with generic applyFilter[T Filterable] and handleFilterKey
- Delete 7 duplicate applyXxxFilter() functions across screens
- Collapse 8 filter-input handlers from 18 to 7 lines each
- Net reduction: ~180 lines of duplicated filter logic

Update() extraction:
- Extract 7 per-domain handleXxxMsg() to respective screen files
- Update() reduced from 374 to 119 lines (68% reduction)
- app.go reduced from 1,076 to 816 lines

Also adds /refactor-review skill and .claude/reports/ to .gitignore
Copy link
Copy Markdown

@amazon-q-developer amazon-q-developer bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

This PR addresses critical version comparison bugs and successfully extracts duplicate code into reusable helpers. The refactoring is well-structured with one critical issue requiring attention.

Critical Issue Found

Version Comparison Logic Error - The compareVersions function silently ignores errors from fmt.Sscanf, which could cause incorrect version comparisons when version strings contain non-numeric characters.

Refactoring Assessment

The DRY extraction and message handler refactoring appear solid:

  • ✅ New filter.go with generic applyFilter[T] and handleFilterKey eliminates ~180 lines of duplication
  • ✅ Domain message handlers properly extracted to screen-specific files
  • Update() method reduced from 374 → 119 lines
  • ✅ Tests added for multi-digit version segments (0.9.0 vs 0.10.0)

Next Steps

Address the version comparison error handling before merging.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Comment on lines +199 to +204
if i < len(aParts) {
fmt.Sscanf(aParts[i], "%d", &ai)
}
if i < len(bParts) {
fmt.Sscanf(bParts[i], "%d", &bi)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛑 Logic Error: fmt.Sscanf silently ignores errors, treating invalid version segments as 0. This causes incorrect version comparisons when segments contain non-numeric characters (e.g., "1.2.beta" vs "1.2.0" would treat "beta" as 0).

Suggested change
if i < len(aParts) {
fmt.Sscanf(aParts[i], "%d", &ai)
}
if i < len(bParts) {
fmt.Sscanf(bParts[i], "%d", &bi)
}
if i < len(aParts) {
n, err := fmt.Sscanf(aParts[i], "%d", &ai)
if err != nil || n != 1 {
return 0 // treat malformed versions as equal
}
}
if i < len(bParts) {
n, err := fmt.Sscanf(bParts[i], "%d", &bi)
if err != nil || n != 1 {
return 0 // treat malformed versions as equal
}
}

- Extract parseVersionSegment helper with proper Sscanf error check
- Non-numeric segments explicitly return 0 instead of silently ignoring
- Add test case for non-numeric version segments (e.g., "0.1.0-beta")
@nathanhuh
Copy link
Copy Markdown
Contributor Author

/q review

Copy link
Copy Markdown

@amazon-q-developer amazon-q-developer bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This refactoring PR successfully addresses the core priorities from the senior review report:

✅ Priority 1 — Version Comparison Bug Fix
The replacement of lexicographic string comparison with proper numeric segment-by-segment comparison is well-implemented. The new compareVersions() and parseVersionSegment() functions correctly handle multi-digit version components, and test coverage includes edge cases like "0.9.0" vs "0.10.0".

⚠️ Priority 2 — Generic Filter Helpers
The extraction of applyFilter[T Filterable]() and handleFilterKey() successfully eliminates duplication. However, there is one critical bug in the case-insensitive filtering logic that must be fixed before merge.

✅ Priority 3 — Extract Update() Handlers
The extraction of domain-specific message handlers is clean and reduces the main Update() function significantly.

Merge Decision: One blocking issue identified that prevents correct filtering functionality. Please address the critical bug in the case-insensitive filter implementation.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

q := strings.ToLower(query)
var result []T
for _, item := range items {
if strings.Contains(item.FilterText(), q) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛑 Logic Error: Case-insensitive filtering is incomplete. While the query is converted to lowercase (line 16), the item's FilterText() output is not. This causes "ABC" to not match query "abc" when it should.

Suggested change
if strings.Contains(item.FilterText(), q) {
if strings.Contains(strings.ToLower(item.FilterText()), q) {

- Apply strings.ToLower to FilterText() output in applyFilter
- Defensive: all current FilterText() already return lowercase, but
  applyFilter should not rely on that convention
@nathanhuh
Copy link
Copy Markdown
Contributor Author

/q review

Copy link
Copy Markdown

@amazon-q-developer amazon-q-developer bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This refactoring PR successfully addresses the stated priorities without introducing any blocking defects. The changes are well-structured and maintain existing functionality.

Key Changes Validated

Version Comparison Bug Fix — The replacement of lexicographic string comparison (l > c) with segment-based integer comparison via compareVersions() correctly fixes the reported bug where "0.9.0" > "0.10.0" would evaluate incorrectly. The implementation properly handles multi-digit version segments, and test coverage validates the fix.

Generic Filter Helpers — The extraction of applyFilter[T Filterable] and handleFilterKey into filter.go eliminates code duplication while preserving functionality. The generic implementation correctly handles case-insensitive filtering and keyboard input.

Message Handler Extraction — The refactoring of domain message handlers into screen-specific files (e.g., handleEC2VPCMsg, handleSecretMsg) reduces app.go complexity without changing behavior. The handler dispatch pattern using a function slice is clean and maintainable.

Testing

All existing tests pass with no behavior changes, confirming this is a safe refactoring that improves code quality without introducing regressions.

Status: Approved — No blocking issues found.


You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.

Copy link
Copy Markdown
Contributor

@jjjjjjeonda86 jjjjjjeonda86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@nathanhuh nathanhuh merged commit 737c9df into main Apr 6, 2026
2 checks passed
@nathanhuh nathanhuh deleted the refactor/review-p1-p2 branch April 6, 2026 04:08
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.

2 participants