fix(types): add tombstone validation and block direct status update (bd-md2, bd-y68)
- Add validation in ValidateWithCustomStatuses() requiring deleted_at for tombstones - Add validation that non-tombstones cannot have deleted_at set - Block direct status update to tombstone in validateStatusWithCustom() - Users must use 'bd delete' instead of 'bd update --status=tombstone' 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -22,8 +22,14 @@ func validateStatus(value interface{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validateStatusWithCustom validates a status value, allowing custom statuses.
|
// validateStatusWithCustom validates a status value, allowing custom statuses.
|
||||||
|
// Note: tombstone status is blocked here (bd-y68) - use bd delete instead of bd update --status=tombstone
|
||||||
func validateStatusWithCustom(value interface{}, customStatuses []string) error {
|
func validateStatusWithCustom(value interface{}, customStatuses []string) error {
|
||||||
if status, ok := value.(string); ok {
|
if status, ok := value.(string); ok {
|
||||||
|
// Block direct status update to tombstone (bd-y68)
|
||||||
|
// Tombstones should only be created via bd delete, not bd update --status=tombstone
|
||||||
|
if types.Status(status) == types.StatusTombstone {
|
||||||
|
return fmt.Errorf("cannot set status to tombstone directly; use 'bd delete' instead")
|
||||||
|
}
|
||||||
if !types.Status(status).IsValidWithCustom(customStatuses) {
|
if !types.Status(status).IsValidWithCustom(customStatuses) {
|
||||||
return fmt.Errorf("invalid status: %s", status)
|
return fmt.Errorf("invalid status: %s", status)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,13 @@ func (i *Issue) ValidateWithCustomStatuses(customStatuses []string) error {
|
|||||||
if i.Status != StatusClosed && i.ClosedAt != nil {
|
if i.Status != StatusClosed && i.ClosedAt != nil {
|
||||||
return fmt.Errorf("non-closed issues cannot have closed_at timestamp")
|
return fmt.Errorf("non-closed issues cannot have closed_at timestamp")
|
||||||
}
|
}
|
||||||
|
// Enforce tombstone invariants (bd-md2): deleted_at must be set for tombstones, and only for tombstones
|
||||||
|
if i.Status == StatusTombstone && i.DeletedAt == nil {
|
||||||
|
return fmt.Errorf("tombstone issues must have deleted_at timestamp")
|
||||||
|
}
|
||||||
|
if i.Status != StatusTombstone && i.DeletedAt != nil {
|
||||||
|
return fmt.Errorf("non-tombstone issues cannot have deleted_at timestamp")
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user