fix(import): support custom issue types during import (#1322)

* fix(import): support custom issue types during import

Fixes regression from 7cf67153 where custom issue types (agent, molecule,
convoy, etc.) were rejected during import with "invalid issue type" error.

- Add validateFieldUpdateWithCustom() for both custom statuses and types
- Add validateIssueTypeWithCustom() for custom type validation
- Update queries.go UpdateIssue() to fetch and validate custom types
- Update transaction.go UpdateIssue() to fetch and validate custom types
- Add 15 test cases covering custom type validation scenarios

This aligns UpdateIssue() validation with the federation trust model used
by ValidateForImport().

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(test): add metadata.json and chdir to temp dir in direct mode tests

Fixes three test failures caused by commit e82f5136 which changed
ensureStoreActive() to use factory.NewFromConfig() instead of respecting
the global dbPath variable.

Root cause:
- Tests create issues in test.db and set dbPath = testDBPath
- ensureStoreActive() calls factory.NewFromConfig() which reads metadata.json
- Without metadata.json, it defaults to beads.db
- Opens empty beads.db instead of test.db with the seeded issues
- Additionally, FindBeadsDir() was finding the real .beads dir, not the test one

Fixes applied:
1. TestFallbackToDirectModeEnablesFlush: Add metadata.json pointing to test.db and chdir to temp dir
2. TestImportFromJSONLInlineAfterDaemonDisconnect: Same fix
3. TestIsBeadsPluginInstalledProjectLevel: Set temp HOME to avoid detecting plugin from real ~/.claude/settings.json

All three tests now pass.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
jonabe
2026-01-25 20:59:47 -05:00
committed by GitHub
parent 119774fa7d
commit d9bd02d952
6 changed files with 123 additions and 9 deletions

View File

@@ -82,15 +82,37 @@ func validateFieldUpdate(key string, value interface{}) error {
return validateFieldUpdateWithCustomStatuses(key, value, nil)
}
// validateFieldUpdateWithCustomStatuses validates a field update value,
// allowing custom statuses for status field validation.
func validateFieldUpdateWithCustomStatuses(key string, value interface{}, customStatuses []string) error {
// validateFieldUpdateWithCustom validates a field update value,
// allowing custom statuses and custom types for their respective field validations.
func validateFieldUpdateWithCustom(key string, value interface{}, customStatuses, customTypes []string) error {
// Special handling for status field to support custom statuses
if key == "status" {
return validateStatusWithCustom(value, customStatuses)
}
// Special handling for issue_type field to support custom types (federation trust model)
if key == "issue_type" {
return validateIssueTypeWithCustom(value, customTypes)
}
if validator, ok := fieldValidators[key]; ok {
return validator(value)
}
return nil
}
// validateFieldUpdateWithCustomStatuses validates a field update value,
// allowing custom statuses for status field validation.
func validateFieldUpdateWithCustomStatuses(key string, value interface{}, customStatuses []string) error {
return validateFieldUpdateWithCustom(key, value, customStatuses, nil)
}
// validateIssueTypeWithCustom validates an issue type value, allowing custom types.
func validateIssueTypeWithCustom(value interface{}, customTypes []string) error {
if issueType, ok := value.(string); ok {
// Normalize first to support aliases like "enhancement" -> "feature"
normalized := types.IssueType(issueType).Normalize()
if !normalized.IsValidWithCustom(customTypes) {
return fmt.Errorf("invalid issue type: %s", issueType)
}
}
return nil
}