feat(types): add HOP entity tracking types (bd-7pwh)
- Add EntityRef type for structured entity references with URI support - Add Creator field to Issue for tracking who created work - Add Validation type and Validations field for proof-of-stake approvals - Fix RemoveDependency FK violation on external deps (bd-a3sj) - Include all new fields in content hash computation - Full test coverage for all new types 🤝 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -221,8 +221,13 @@ func (s *SQLiteStorage) RemoveDependency(ctx context.Context, issueID, dependsOn
|
||||
return fmt.Errorf("failed to record event: %w", err)
|
||||
}
|
||||
|
||||
// Mark both issues as dirty for incremental export
|
||||
if err := markIssuesDirtyTx(ctx, tx, []string{issueID, dependsOnID}); err != nil {
|
||||
// Mark issues as dirty for incremental export
|
||||
// For external refs, only mark the source issue (target doesn't exist locally)
|
||||
issueIDsToMark := []string{issueID}
|
||||
if !strings.HasPrefix(dependsOnID, "external:") {
|
||||
issueIDsToMark = append(issueIDsToMark, dependsOnID)
|
||||
}
|
||||
if err := markIssuesDirtyTx(ctx, tx, issueIDsToMark); err != nil {
|
||||
return wrapDBError("mark issues dirty after removing dependency", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -1610,3 +1610,50 @@ func TestDetectCycles_RelatesTypeAllowsBidirectionalWithoutCycleReport(t *testin
|
||||
t.Error("Expected B to relate-to A")
|
||||
}
|
||||
}
|
||||
|
||||
// TestRemoveDependencyExternal verifies that removing an external dependency
|
||||
// doesn't cause FK violation (bd-a3sj). External refs like external:project:capability
|
||||
// don't exist in the issues table, so we must not mark them as dirty.
|
||||
func TestRemoveDependencyExternal(t *testing.T) {
|
||||
store, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Create an issue
|
||||
issue := &types.Issue{
|
||||
Title: "Issue with external dep",
|
||||
Status: types.StatusOpen,
|
||||
Priority: 1,
|
||||
IssueType: types.TypeTask,
|
||||
}
|
||||
if err := store.CreateIssue(ctx, issue, "test-user"); err != nil {
|
||||
t.Fatalf("CreateIssue failed: %v", err)
|
||||
}
|
||||
|
||||
// Add an external dependency
|
||||
externalRef := "external:other-project:some-capability"
|
||||
dep := &types.Dependency{
|
||||
IssueID: issue.ID,
|
||||
DependsOnID: externalRef,
|
||||
Type: types.DepBlocks,
|
||||
}
|
||||
if err := store.AddDependency(ctx, dep, "test-user"); err != nil {
|
||||
t.Fatalf("AddDependency failed: %v", err)
|
||||
}
|
||||
|
||||
// This should NOT cause FK violation (the bug was marking external ref as dirty)
|
||||
err := store.RemoveDependency(ctx, issue.ID, externalRef, "test-user")
|
||||
if err != nil {
|
||||
t.Fatalf("RemoveDependency on external ref should succeed, got: %v", err)
|
||||
}
|
||||
|
||||
// Verify dependency was actually removed
|
||||
deps, err := store.GetDependencyRecords(ctx, issue.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("GetDependencyRecords failed: %v", err)
|
||||
}
|
||||
if len(deps) != 0 {
|
||||
t.Errorf("Expected 0 dependencies after removal, got %d", len(deps))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user