Fix bd-206: Handle status transitions and closed_at constraint

- Updated manageClosedAt to handle both string and types.Status type assertions
- Added equalTime function for comparing timestamps in import change detection
- Added tests for open→closed and closed→open transitions
- Added comment clarifying closed_at is managed automatically

The bug occurred when UpdateIssue received types.Status instead of string,
causing manageClosedAt to skip setting closed_at when status changed to closed.

Amp-Thread-ID: https://ampcode.com/threads/T-ee774f6d-3b90-4311-976d-60c8dd8fe677
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-27 19:14:46 -07:00
parent 299d1c2c21
commit db1458bfed
5 changed files with 175 additions and 6 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"sort"
"strings"
"time"
"github.com/steveyegge/beads/internal/importer"
"github.com/steveyegge/beads/internal/storage"
@@ -114,6 +115,29 @@ func (fc *fieldComparator) equalPriority(existing int, newVal interface{}) bool
return existing == int(p)
}
// equalTime compares *time.Time field
func (fc *fieldComparator) equalTime(existing *time.Time, newVal interface{}) bool {
switch t := newVal.(type) {
case *time.Time:
if existing == nil && t == nil {
return true
}
if existing == nil || t == nil {
return false
}
return existing.Equal(*t)
case time.Time:
if existing == nil {
return false
}
return existing.Equal(t)
case nil:
return existing == nil
default:
return false
}
}
// checkFieldChanged checks if a specific field has changed
func (fc *fieldComparator) checkFieldChanged(key string, existing *types.Issue, newVal interface{}) bool {
switch key {
@@ -137,6 +161,8 @@ func (fc *fieldComparator) checkFieldChanged(key string, existing *types.Issue,
return !fc.equalStr(existing.Assignee, newVal)
case "external_ref":
return !fc.equalPtrStr(existing.ExternalRef, newVal)
case "closed_at":
return !fc.equalTime(existing.ClosedAt, newVal)
default:
// Unknown field - treat as changed to be conservative
// This prevents skipping updates when new fields are added